[libcxx-commits] [libcxx] [libc++] fix minor performance issue in `basic_string<C>::append()` (PR #210078)
Pavel Novikov via libcxx-commits
libcxx-commits at lists.llvm.org
Fri Jul 17 07:12:09 PDT 2026
toughengineer wrote:
Here's a reasonable and realistic (in my opinion) example:
```c++
// given some string like input, e.g.
std::string_view input;
// and also some locale and output
std::locale locale;
std::string output;
// ...
auto p = input |
std::views::filter([&locale](char c) { return std::isprint(c, locale); });
output.append(p.begin(), p.end());
```
Even this almost trivial example demostrates the performance issue:
<img width="1210" height="681" alt="ranges" src="https://github.com/user-attachments/assets/9a812657-cca9-47b2-a979-7656c9ec68e5" />
<details><summary>benchmark output before</summary>
```
2026-07-17T16:36:18+03:00
Running ./string_append
Run on (20 X 3494.4 MHz CPU s)
CPU Caches:
L1 Data 48 KiB (x10)
L1 Instruction 32 KiB (x10)
L2 Unified 2048 KiB (x10)
L3 Unified 24576 KiB (x1)
Load Average: 0.36, 0.18, 0.16
-------------------------------------------------------------------------------
Benchmark Time CPU Iterations UserCounters...
-------------------------------------------------------------------------------
bench_ranges/1 9.03 ns 9.03 ns 79388662 t/i=9.031ns
bench_ranges/2 19.7 ns 19.7 ns 35723581 t/i=9.84356ns
bench_ranges/4 36.1 ns 36.1 ns 19531441 t/i=9.0152ns
bench_ranges/8 69.0 ns 69.0 ns 9956207 t/i=8.62202ns
bench_ranges/16 125 ns 125 ns 5613594 t/i=7.84345ns
bench_ranges/32 247 ns 247 ns 2822421 t/i=7.72773ns
bench_ranges/64 516 ns 516 ns 1372805 t/i=8.05528ns
bench_ranges/128 992 ns 992 ns 694859 t/i=7.75294ns
bench_ranges/256 1958 ns 1958 ns 351618 t/i=7.6484ns
bench_ranges/512 3927 ns 3927 ns 179205 t/i=7.66954ns
bench_ranges/1024 7838 ns 7838 ns 90166 t/i=7.65432ns
bench_ranges/2048 21615 ns 21615 ns 32478 t/i=10.5541ns
bench_ranges/4096 52982 ns 52980 ns 13421 t/i=12.9345ns
bench_ranges/8192 117859 ns 117857 ns 6034 t/i=14.3868ns
bench_ranges/16384 255739 ns 255729 ns 2737 t/i=15.6085ns
bench_ranges/32768 527432 ns 527419 ns 1344 t/i=16.0956ns
bench_ranges/65536 1070200 ns 1070150 ns 641 t/i=16.3292ns
bench_ranges/131072 2134541 ns 2134475 ns 322 t/i=16.2848ns
bench_ranges/262144 4311675 ns 4311642 ns 164 t/i=16.4476ns
bench_ranges/524288 8571076 ns 8570984 ns 81 t/i=16.3479ns
bench_ranges/1048576 17185996 ns 17185873 ns 41 t/i=16.3897ns
```
</details>
<details><summary>benchmark output after</summary>
```
2026-07-17T16:37:09+03:00
Running ./string_append
Run on (20 X 3494.4 MHz CPU s)
CPU Caches:
L1 Data 48 KiB (x10)
L1 Instruction 32 KiB (x10)
L2 Unified 2048 KiB (x10)
L3 Unified 24576 KiB (x1)
Load Average: 0.39, 0.22, 0.18
-------------------------------------------------------------------------------
Benchmark Time CPU Iterations UserCounters...
-------------------------------------------------------------------------------
bench_ranges/1 8.40 ns 8.40 ns 86345986 t/i=8.40176ns
bench_ranges/2 15.6 ns 15.6 ns 44261217 t/i=7.80893ns
bench_ranges/4 26.5 ns 26.5 ns 26726279 t/i=6.61509ns
bench_ranges/8 49.7 ns 49.7 ns 14098475 t/i=6.20786ns
bench_ranges/16 85.9 ns 85.9 ns 8259402 t/i=5.36759ns
bench_ranges/32 169 ns 169 ns 3998519 t/i=5.27777ns
bench_ranges/64 349 ns 349 ns 1987558 t/i=5.45099ns
bench_ranges/128 683 ns 683 ns 1039694 t/i=5.33238ns
bench_ranges/256 1338 ns 1338 ns 517963 t/i=5.22682ns
bench_ranges/512 2631 ns 2631 ns 266303 t/i=5.13823ns
bench_ranges/1024 5245 ns 5245 ns 133538 t/i=5.1224ns
bench_ranges/2048 10921 ns 10920 ns 64641 t/i=5.33222ns
bench_ranges/4096 29330 ns 29329 ns 23693 t/i=7.16048ns
bench_ranges/8192 71116 ns 71114 ns 9436 t/i=8.68086ns
bench_ranges/16384 163212 ns 163205 ns 4357 t/i=9.96126ns
bench_ranges/32768 343948 ns 343942 ns 2012 t/i=10.4963ns
bench_ranges/65536 699559 ns 699560 ns 958 t/i=10.6744ns
bench_ranges/131072 1416766 ns 1416731 ns 497 t/i=10.8088ns
bench_ranges/262144 2861586 ns 2861507 ns 243 t/i=10.9158ns
bench_ranges/524288 5745899 ns 5745906 ns 120 t/i=10.9594ns
bench_ranges/1048576 11501892 ns 11501800 ns 62 t/i=10.969ns
```
</details>
In general the performance difference may be unbounded due to unbounded complexity of the processing.
The code may be garbage (like in this example), but I think you should not penalize the code on top of that.
https://github.com/llvm/llvm-project/pull/210078
More information about the libcxx-commits
mailing list