[llvm-branch-commits] [libcxx] [libc++][format][4/7] Improves std::format_to performance. (PR #101823)
via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Sat Aug 3 06:55:52 PDT 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-libcxx
Author: Mark de Wever (mordante)
<details>
<summary>Changes</summary>
This changes the __output_buffer users for format_to to the new structure. It also uses the new allocating buffer to improve performance.
write_double_comparison:
Before
----------------------------------------------------------------------------------------
Benchmark Time CPU Iterations
----------------------------------------------------------------------------------------
BM_sprintf 197 ns 197 ns 3537000
BM_to_string 219 ns 219 ns 3200000
BM_to_chars 42.3 ns 42.3 ns 16490000
BM_to_chars_as_string 48.1 ns 48.1 ns 14508000
BM_format 167 ns 167 ns 4207000
BM_format_to_back_inserter<std::string> 179 ns 179 ns 3914000
BM_format_to_back_inserter<std::vector<char>> 216 ns 216 ns 3234000
BM_format_to_back_inserter<std::list<char>> 752 ns 752 ns 932000
BM_format_to_iterator/<std::array> 165 ns 165 ns 4257000
BM_format_to_iterator/<std::string> 165 ns 165 ns 4251000
BM_format_to_iterator/<std::vector> 165 ns 165 ns 4254000
After
----------------------------------------------------------------------------------------
Benchmark Time CPU Iterations
----------------------------------------------------------------------------------------
BM_sprintf 197 ns 197 ns 3548000
BM_to_string 219 ns 219 ns 3203000
BM_to_chars 42.3 ns 42.3 ns 16540000
BM_to_chars_as_string 48.2 ns 48.2 ns 14532000
BM_format 167 ns 167 ns 4190000
BM_format_to_back_inserter<std::string> 176 ns 176 ns 3959000
BM_format_to_back_inserter<std::vector<char>> 211 ns 211 ns 3312000
BM_format_to_back_inserter<std::list<char>> 752 ns 752 ns 934000
BM_format_to_iterator/<std::array> 162 ns 162 ns 4313000
BM_format_to_iterator/<std::string> 162 ns 162 ns 4307000
BM_format_to_iterator/<std::vector> 162 ns 162 ns 4308000
Comparison
Benchmark Time CPU Time Old Time New CPU Old CPU New
--------------------------------------------------------------------------------------------------------------------------------------------
BM_sprintf +0.0003 +0.0002 197 197 197 197
BM_to_string -0.0004 -0.0004 219 219 219 219
BM_to_chars +0.0003 +0.0003 42 42 42 42
BM_to_chars_as_string +0.0004 +0.0004 48 48 48 48
BM_format +0.0016 +0.0016 167 167 167 167
BM_format_to_back_inserter<std::string> -0.0128 -0.0127 179 176 179 176
BM_format_to_back_inserter<std::vector<char>> -0.0216 -0.0216 216 211 216 211
BM_format_to_back_inserter<std::list<char>> -0.0008 -0.0008 752 752 752 752
BM_format_to_iterator/<std::array> -0.0137 -0.0137 165 162 165 162
BM_format_to_iterator/<std::string> -0.0154 -0.0153 165 162 165 162
BM_format_to_iterator/<std::vector> -0.0138 -0.0138 165 162 165 162
OVERALL_GEOMEAN -0.0069 -0.0069 0 0 0 0
write_int_comparison:
Before
----------------------------------------------------------------------------------------
Benchmark Time CPU Iterations
----------------------------------------------------------------------------------------
BM_sprintf 80.3 ns 80.1 ns 8703000
BM_to_string 15.0 ns 14.9 ns 46849000
BM_to_chars 4.94 ns 4.92 ns 139052000
BM_to_chars_as_string 15.6 ns 15.6 ns 44945000
BM_format 62.1 ns 61.9 ns 11302000
BM_format_to_back_inserter<std::string> 70.3 ns 70.1 ns 9984000
BM_format_to_back_inserter<std::vector<char>> 92.9 ns 92.7 ns 7520000
BM_format_to_back_inserter<std::list<char>> 239 ns 239 ns 2926000
BM_format_to_iterator/<std::array> 60.6 ns 60.4 ns 11582000
BM_format_to_iterator/<std::string> 60.2 ns 60.0 ns 11671000
BM_format_to_iterator/<std::vector> 60.1 ns 60.0 ns 11691000
After
----------------------------------------------------------------------------------------
Benchmark Time CPU Iterations
----------------------------------------------------------------------------------------
BM_sprintf 81.3 ns 81.2 ns 8546000
BM_to_string 14.9 ns 14.9 ns 46809000
BM_to_chars 4.93 ns 4.93 ns 138278000
BM_to_chars_as_string 15.4 ns 15.4 ns 45504000
BM_format 62.0 ns 61.9 ns 11330000
BM_format_to_back_inserter<std::string> 69.0 ns 68.9 ns 10164000
BM_format_to_back_inserter<std::vector<char>> 90.4 ns 90.3 ns 7736000
BM_format_to_back_inserter<std::list<char>> 242 ns 242 ns 2891000
BM_format_to_iterator/<std::array> 58.6 ns 58.6 ns 11952000
BM_format_to_iterator/<std::string> 58.2 ns 58.1 ns 12052000
BM_format_to_iterator/<std::vector> 58.4 ns 58.3 ns 11983000
Comparison
Benchmark Time CPU Time Old Time New CPU Old CPU New
--------------------------------------------------------------------------------------------------------------------------------------------
BM_sprintf +0.0116 +0.0132 80 81 80 81
BM_to_string -0.0050 -0.0036 15 15 15 15
BM_to_chars -0.0005 +0.0010 5 5 5 5
BM_to_chars_as_string -0.0168 -0.0149 16 15 16 15
BM_format -0.0015 +0.0001 62 62 62 62
BM_format_to_back_inserter<std::string> -0.0186 -0.0172 70 69 70 69
BM_format_to_back_inserter<std::vector<char>> -0.0271 -0.0256 93 90 93 90
BM_format_to_back_inserter<std::list<char>> +0.0104 +0.0119 239 242 239 242
BM_format_to_iterator/<std::array> -0.0322 -0.0304 61 59 60 59
BM_format_to_iterator/<std::string> -0.0330 -0.0317 60 58 60 58
BM_format_to_iterator/<std::vector> -0.0285 -0.0270 60 58 60 58
OVERALL_GEOMEAN -0.0130 -0.0114 0 0 0 0
write_string_comparison:
Comparison
Benchmark Time CPU Time Old Time New CPU Old CPU New
-------------------------------------------------------------------------------------------------------------------------------------------------------------------
BM_sprintf/C string len = 6 -0.0037 -0.0051 4 4 4 4
BM_format/C string len = 6 -0.0022 -0.0037 50 49 50 49
BM_format_to_back_inserter<std::string>/C string len = 6 -0.0136 -0.0151 57 56 57 56
BM_format_to_back_inserter<std::vector<char>>/C string len = 6 +0.0408 +0.0392 73 76 73 76
BM_format_to_back_inserter<std::deque<char>>/C string len = 6 +0.0115 +0.0099 156 158 156 157
BM_format_to_back_inserter<std::list<char>>/C string len = 6 +0.0325 +0.0307 136 140 136 140
BM_format_to_iterator/<std::array> C string len = 6 -0.0153 -0.0167 47 46 47 46
BM_format_to_iterator/<std::string> C string len = 6 -0.0332 -0.0346 47 46 47 46
BM_format_to_iterator/<std::vector> C string len = 6 -0.0125 -0.0141 46 46 46 46
BM_format_to_iterator/<std::deque> C string len = 6 +0.0041 +0.0026 52 53 52 53
BM_format/string len = 6 -0.0170 -0.0185 50 49 50 49
BM_format_to_back_inserter<std::string>/string len = 6 -0.0092 -0.0106 56 55 56 55
BM_format_to_back_inserter<std::vector<char>>/string len = 6 +0.0153 +0.0138 73 74 73 74
BM_format_to_back_inserter<std::deque<char>>/string len = 6 +0.0392 +0.0371 155 161 154 160
BM_format_to_back_inserter<std::list<char>>/string len = 6 +0.0367 +0.0351 133 138 133 138
BM_format_to_iterator/<std::array> string len = 6 -0.0107 -0.0125 47 46 47 46
BM_format_to_iterator/<std::string> string len = 6 -0.0312 -0.0326 47 46 47 46
BM_format_to_iterator/<std::vector> string len = 6 -0.0103 -0.0144 46 46 46 46
BM_format_to_iterator/<std::deque> string len = 6 -0.0042 -0.0057 53 53 53 52
BM_format/string_view len = 6 -0.0191 -0.0206 49 48 49 48
BM_format_to_back_inserter<std::string>/string_view len = 6 -0.0283 -0.0298 56 55 56 54
BM_format_to_back_inserter<std::vector<char>>/string_view len = 6 +0.0408 +0.0389 72 75 72 75
BM_format_to_back_inserter<std::deque<char>>/string_view len = 6 +0.0214 +0.0199 153 157 153 156
BM_format_to_back_inserter<std::list<char>>/string_view len = 6 +0.0407 +0.0393 132 137 132 137
BM_format_to_iterator/<std::array> string_view len = 6 -0.0235 -0.0249 46 45 46 45
BM_format_to_iterator/<std::string> string_view len = 6 -0.0368 -0.0385 46 45 46 44
BM_format_to_iterator/<std::vector> string_view len = 6 -0.0293 -0.0308 46 45 46 45
BM_format_to_iterator/<std::deque> string_view len = 6 +0.0094 +0.0079 52 52 52 52
BM_sprintf/C string len = 60 -0.0004 -0.0018 5 5 5 5
BM_format/C string len = 60 +0.0250 +0.0232 64 65 64 65
BM_format_to_back_inserter<std::string>/C string len = 60 -0.0027 -0.0041 75 75 75 75
BM_format_to_back_inserter<std::vector<char>>/C string len = 60 +0.0228 +0.0233 89 91 89 91
BM_format_to_back_inserter<std::deque<char>>/C string len = 60 +0.0303 +0.0312 285 294 285 294
BM_format_to_back_inserter<std::list<char>>/C string len = 60 +0.0419 +0.0429 1164 1212 1163 1212
BM_format_to_iterator/<std::array> C string len = 60 -0.0154 -0.0145 46 46 46 46
BM_format_to_iterator/<std::string> C string len = 60 -0.0355 -0.0345 47 45 47 45
BM_format_to_iterator/<std::vector> C string len = 60 -0.0161 -0.0152 46 46 46 46
BM_format_to_iterator/<std::deque> C string len = 60 +0.0044 +0.0054 52 52 52 52
BM_format/string len = 60 +0.0268 +0.0278 62 64 62 64
BM_format_to_back_inserter<std::string>/string len = 60 -0.0031 -0.0022 75 74 75 74
BM_format_to_back_inserter<std::vector<char>>/string len = 60 +0.0183 +0.0191 87 88 86 88
BM_format_to_back_inserter<std::deque<char>>/string len = 60 +0.0567 +0.0578 279 295 279 295
BM_format_to_back_inserter<std::list<char>>/string len = 60 +0.0386 +0.0396 1167 1212 1165 1212
BM_format_to_iterator/<std::array> string len = 60 -0.0094 -0.0084 47 46 47 46
BM_format_to_iterator/<std::string> string len = 60 -0.0268 -0.0259 47 46 47 46
BM_format_to_iterator/<std::vector> string len = 60 -0.0082 -0.0073 46 46 46 46
BM_format_to_iterator/<std::deque> string len = 60 +0.0254 +0.0264 52 54 52 54
BM_format/string_view len = 60 -0.0084 -0.0075 62 62 62 62
BM_format_to_back_inserter<std::string>/string_view len = 60 -0.0001 +0.0008 74 74 74 74
BM_format_to_back_inserter<std::vector<char>>/string_view len = 60 +0.0145 +0.0154 86 88 86 88
BM_format_to_back_inserter<std::deque<char>>/string_view len = 60 +0.0411 +0.0420 279 291 279 291
BM_format_to_back_inserter<std::list<char>>/string_view len = 60 +0.0358 +0.0368 1164 1205 1163 1205
BM_format_to_iterator/<std::array> string_view len = 60 -0.0306 -0.0297 47 45 47 45
BM_format_to_iterator/<std::string> string_view len = 60 -0.0321 -0.0312 46 45 46 45
BM_format_to_iterator/<std::vector> string_view len = 60 -0.0320 -0.0311 46 45 46 45
BM_format_to_iterator/<std::deque> string_view len = 60 +0.0039 +0.0048 52 52 52 52
BM_sprintf/C string len = 6000 +0.4788 +0.4802 77 114 77 114
BM_format/C string len = 6000 -0.0087 -0.0078 345 342 345 342
BM_format_to_back_inserter<std::string>/C string len = 6000 +0.0104 +0.0114 1001 1011 1000 1011
BM_format_to_back_inserter<std::vector<char>>/C string len = 6000 +0.0195 +0.0206 972 991 971 991
BM_format_to_back_inserter<std::deque<char>>/C string len = 6000 -0.0092 -0.0082 15129 14990 15114 14990
BM_format_to_back_inserter<std::list<char>>/C string len = 6000 -0.0017 -0.0007 115290 115092 115167 115090
BM_format_to_iterator/<std::array> C string len = 6000 -0.0136 -0.0127 161 159 161 159
BM_format_to_iterator/<std::string> C string len = 6000 -0.0442 -0.0433 154 147 154 147
BM_format_to_iterator/<std::vector> C string len = 6000 -0.0148 -0.0139 150 148 150 148
BM_format_to_iterator/<std::deque> C string len = 6000 -0.3357 -0.3350 463 308 463 308
BM_format/string len = 6000 +0.0329 +0.0341 282 291 281 291
BM_format_to_back_inserter<std::string>/string len = 6000 +0.0289 +0.0299 941 968 940 968
BM_format_to_back_inserter<std::vector<char>>/string len = 6000 +0.0058 +0.0068 933 938 932 938
BM_format_to_back_inserter<std::deque<char>>/string len = 6000 -0.0053 -0.0043 15110 15029 15095 15030
BM_format_to_back_inserter<std::list<char>>/string len = 6000 +0.0041 +0.0065 115131 115601 114854 115597
BM_format_to_iterator/<std::array> string len = 6000 -0.0028 +0.0000 119 118 118 118
BM_format_to_iterator/<std::string> string len = 6000 -0.0214 -0.0190 108 105 107 105
BM_format_to_iterator/<std::vector> string len = 6000 -0.0125 -0.0100 107 105 107 105
BM_format_to_iterator/<std::deque> string len = 6000 -0.3286 -0.3269 395 265 394 265
BM_format/string_view len = 6000 +0.0084 +0.0110 282 284 281 284
BM_format_to_back_inserter<std::string>/string_view len = 6000 +0.0347 +0.0373 936 969 934 969
BM_format_to_back_inserter<std::vector<char>>/string_view len = 6000 +0.0148 +0.0173 925 938 922 938
BM_format_to_back_inserter<std::deque<char>>/string_view len = 6000 -0.0049 -0.0025 15072 14999 15036 14999
BM_format_to_back_inserter<std::list<char>>/string_view len = 6000 +0.0017 +0.0040 115332 115524 115059 115520
BM_format_to_iterator/<std::array> string_view len = 6000 -0.0174 -0.0147 119 117 119 117
BM_format_to_iterator/<std::string> string_view len = 6000 -0.0269 -0.0245 108 105 107 105
BM_format_to_iterator/<std::vector> string_view len = 6000 -0.0226 -0.0202 107 105 107 105
BM_format_to_iterator/<std::deque> string_view len = 6000 -0.3463 -0.3447 392 256 391 256
OVERALL_GEOMEAN -0.0089 -0.0087 0 0 0 0
format_to:
Before
--------------------------------------------------------------------------------------------------------------------------
Benchmark Time CPU Iterations UserCounters...
--------------------------------------------------------------------------------------------------------------------------
BM_format_to_string_back_inserter<std::string>/1 55.3 ns 55.2 ns 12600282 bytes_per_second=17.2841Mi/s
BM_format_to_string_back_inserter<std::string>/2 55.3 ns 55.2 ns 12711392 bytes_per_second=34.584Mi/s
BM_format_to_string_back_inserter<std::string>/4 55.3 ns 55.2 ns 12668346 bytes_per_second=69.1337Mi/s
BM_format_to_string_back_inserter<std::string>/8 55.0 ns 54.8 ns 12806254 bytes_per_second=139.148Mi/s
BM_format_to_string_back_inserter<std::string>/16 55.0 ns 54.9 ns 12771640 bytes_per_second=278.038Mi/s
BM_format_to_string_back_inserter<std::string>/32 74.3 ns 74.1 ns 9425332 bytes_per_second=411.691Mi/s
BM_format_to_string_back_inserter<std::string>/64 74.3 ns 74.1 ns 9467958 bytes_per_second=823.72Mi/s
BM_format_to_string_back_inserter<std::string>/128 75.6 ns 75.4 ns 9244814 bytes_per_second=1.58012Gi/s
BM_format_to_string_back_inserter<std::string>/256 90.4 ns 90.1 ns 7758708 bytes_per_second=2.64476Gi/s
BM_format_to_string_back_inserter<std::string>/512 136 ns 135 ns 5171079 bytes_per_second=3.52016Gi/s
BM_format_to_string_back_inserter<std::string>/1024 253 ns 252 ns 2766944 bytes_per_second=3.77704Gi/s
BM_format_to_string_back_inserter<std::string>/2048 410 ns 409 ns 1711155 bytes_per_second=4.66192Gi/s
BM_format_to_string_back_inserter<std::string>/4096 662 ns 660 ns 1063114 bytes_per_second=5.77795Gi/s
BM_format_to_string_back_inserter<std::string>/8192 1124 ns 1121 ns 626215 bytes_per_second=6.80694Gi/s
BM_format_to_string_back_inserter<std::string>/16384 2228 ns 2222 ns 315523 bytes_per_second=6.86706Gi/s
BM_format_to_string_back_inserter<std::string>/32768 4795 ns 4783 ns 146357 bytes_per_second=6.38068Gi/s
BM_format_to_string_back_inserter<std::string>/65536 8433 ns 8412 ns 83268 bytes_per_second=7.25532Gi/s
BM_format_to_string_back_inserter<std::string>/131072 44973 ns 44732 ns 15650 bytes_per_second=2.7289Gi/s
BM_format_to_string_back_inserter<std::string>/262144 134871 ns 134517 ns 5205 bytes_per_second=1.81495Gi/s
BM_format_to_string_back_inserter<std::string>/524288 316669 ns 316613 ns 2208 bytes_per_second=1.5422Gi/s
BM_format_to_string_back_inserter<std::string>/1048576 677580 ns 677582 ns 1036 bytes_per_second=1.44125Gi/s
BM_format_to_string_back_inserter<std::vector<char>>/1 69.9 ns 69.9 ns 9994480 bytes_per_second=13.6348Mi/s
BM_format_to_string_back_inserter<std::vector<char>>/2 70.1 ns 70.1 ns 9995724 bytes_per_second=27.2205Mi/s
BM_format_to_string_back_inserter<std::vector<char>>/4 71.3 ns 71.3 ns 9850375 bytes_per_second=53.5283Mi/s
BM_format_to_string_back_inserter<std::vector<char>>/8 73.8 ns 73.8 ns 9486647 bytes_per_second=103.44Mi/s
BM_format_to_string_back_inserter<std::vector<char>>/16 78.7 ns 78.7 ns 8873541 bytes_per_second=193.765Mi/s
BM_format_to_string_back_inserter<std::vector<char>>/32 88.7 ns 88.7 ns 7913676 bytes_per_second=344.039Mi/s
BM_format_to_string_back_inserter<std::vector<char>>/64 90.2 ns 90.2 ns 7740112 bytes_per_second=676.676Mi/s
BM_format_to_string_back_inserter<std::vector<char>>/128 92.2 ns 92.2 ns 7569110 bytes_per_second=1.29352Gi/s
BM_format_to_string_back_inserter<std::vector<char>>/256 106 ns 106 ns 6612544 bytes_per_second=2.25002Gi/s
BM_format_to_string_back_inserter<std::vector<char>>/512 163 ns 163 ns 4299613 bytes_per_second=2.9327Gi/s
BM_format_to_string_back_inserter<std::vector<char>>/1024 240 ns 240 ns 2919691 bytes_per_second=3.98065Gi/s
BM_format_to_string_back_inserter<std::vector<char>>/2048 400 ns 400 ns 1749907 bytes_per_second=4.76489Gi/s
BM_format_to_string_back_inserter<std::vector<char>>/4096 635 ns 635 ns 1101669 bytes_per_second=6.00718Gi/s
BM_format_to_string_back_inserter<std::vector<char>>/8192 1064 ns 1064 ns 655668 bytes_per_second=7.17313Gi/s
BM_format_to_string_back_inserter<std::vector<char>>/16384 1986 ns 1986 ns 352665 bytes_per_second=7.68268Gi/s
BM_format_to_string_back_inserter<std::vector<char>>/32768 3834 ns 3835 ns 182295 bytes_per_second=7.95861Gi/s
BM_format_to_string_back_inserter<std::vector<char>>/65536 7388 ns 7388 ns 94038 bytes_per_second=8.26153Gi/s
BM_format_to_string_back_inserter<std::vector<char>>/131072 17454 ns 17454 ns 40109 bytes_per_second=6.99363Gi/s
BM_format_to_string_back_inserter<std::vector<char>>/262144 36133 ns 36133 ns 19353 bytes_per_second=6.75666Gi/s
BM_format_to_string_back_inserter<std::vector<char>>/524288 73310 ns 73310 ns 9556 bytes_per_second=6.66053Gi/s
BM_format_to_string_back_inserter<std::vector<char>>/1048576 145001 ns 144996 ns 4828 bytes_per_second=6.73509Gi/s
BM_format_to_string_back_inserter<std::list<char>>/1 62.9 ns 62.9 ns 11119088 bytes_per_second=15.1622Mi/s
BM_format_to_string_back_inserter<std::list<char>>/2 76.0 ns 76.0 ns 9212976 bytes_per_second=25.0904Mi/s
BM_format_to_string_back_inserter<std::list<char>>/4 103 ns 103 ns 6740929 bytes_per_second=36.8618Mi/s
BM_format_to_string_back_inserter<std::list<char>>/8 171 ns 171 ns 4096894 bytes_per_second=44.6147Mi/s
BM_format_to_string_back_inserter<std::list<char>>/16 324 ns 324 ns 2147006 bytes_per_second=47.0328Mi/s
BM_format_to_string_back_inserter<std::list<char>>/32 638 ns 638 ns 1096597 bytes_per_second=47.799Mi/s
BM_format_to_string_back_inserter<std::list<char>>/64 1230 ns 1230 ns 570396 bytes_per_second=49.6318Mi/s
BM_format_to_string_back_inserter<std::list<char>>/128 2427 ns 2427 ns 289550 bytes_per_second=50.306Mi/s
BM_format_to_string_back_inserter<std::list<char>>/256 4847 ns 4847 ns 144614 bytes_per_second=50.3648Mi/s
BM_format_to_string_back_inserter<std::list<char>>/512 9656 ns 9656 ns 72476 bytes_per_second=50.5676Mi/s
BM_format_to_string_back_inserter<std::list<char>>/1024 19415 ns 19416 ns 35934 bytes_per_second=50.298Mi/s
BM_format_to_string_back_inserter<std::list<char>>/2048 38927 ns 38928 ns 17986 bytes_per_second=50.173Mi/s
BM_format_to_string_back_inserter<std::list<char>>/4096 78062 ns 78064 ns 8967 bytes_per_second=50.0392Mi/s
BM_format_to_string_back_inserter<std::list<char>>/8192 156624 ns 156628 ns 4464 bytes_per_second=49.8795Mi/s
BM_format_to_string_back_inserter<std::list<char>>/16384 313781 ns 313788 ns 2232 bytes_per_second=49.7948Mi/s
BM_format_to_string_back_inserter<std::list<char>>/32768 626674 ns 626667 ns 1112 bytes_per_second=49.867Mi/s
BM_format_to_string_back_inserter<std::list<char>>/65536 1248918 ns 1248933 ns 558 bytes_per_second=50.0427Mi/s
BM_format_to_string_back_inserter<std::list<char>>/131072 2512031 ns 2511949 ns 277 bytes_per_second=49.7622Mi/s
BM_format_to_string_back_inserter<std::list<char>>/262144 5118786 ns 5118308 ns 126 bytes_per_second=48.8443Mi/s
BM_format_to_string_back_inserter<std::list<char>>/524288 10395742 ns 10395288 ns 63 bytes_per_second=48.0987Mi/s
BM_format_to_string_back_inserter<std::list<char>>/1048576 21110172 ns 21110073 ns 31 bytes_per_second=47.3708Mi/s
BM_format_to_string_begin<std::string>/1 47.0 ns 47.0 ns 14928464 bytes_per_second=20.2942Mi/s
BM_format_to_string_begin<std::string>/2 47.0 ns 47.0 ns 14889677 bytes_per_second=40.5641Mi/s
BM_format_to_string_begin<std::string>/4 47.1 ns 47.1 ns 14877893 bytes_per_second=81.0735Mi/s
BM_format_to_string_begin<std::string>/8 47.0 ns 47.0 ns 14855791 bytes_per_second=162.307Mi/s
BM_format_to_string_begin<std::string>/16 47.1 ns 47.1 ns 14867291 bytes_per_second=324.274Mi/s
BM_format_to_string_begin<std::string>/32 47.0 ns 47.0 ns 14863938 bytes_per_second=649.013Mi/s
BM_format_to_string_begin<std::string>/64 46.5 ns 46.5 ns 14004459 bytes_per_second=1.28171Gi/s
BM_format_to_string_begin<std::string>/128 47.1 ns 47.1 ns 14831108 bytes_per_second=2.53299Gi/s
BM_format_to_string_begin<std::string>/256 51.6 ns 51.6 ns 13604783 bytes_per_second=4.62228Gi/s
BM_format_to_string_begin<std::string>/512 50.0 ns 50.0 ns 13980138 bytes_per_second=9.53155Gi/s
BM_format_to_string_begin<std::string>/1024 59.2 ns 59.2 ns 11872452 bytes_per_second=16.1221Gi/s
BM_format_to_string_begin<std::string>/2048 69.0 ns 69.0 ns 10128771 bytes_per_second=27.6377Gi/s
BM_format_to_string_begin<std::string>/4096 100 ns 100 ns 6963452 bytes_per_second=38.0663Gi/s
BM_format_to_string_begin<std::string>/8192 151 ns 151 ns 4635381 bytes_per_second=50.5416Gi/s
BM_format_to_string_begin<std::string>/16384 314 ns 314 ns 2233442 bytes_per_second=48.5983Gi/s
BM_format_to_string_begin<std::string>/32768 1336 ns 1336 ns 524989 bytes_per_second=22.8492Gi/s
BM_format_to_string_begin<std::string>/65536 3763 ns 3763 ns 185762 bytes_per_second=16.2188Gi/s
BM_format_to_string_begin<std::string>/131072 6556 ns 6556 ns 106616 bytes_per_second=18.6207Gi/s
BM_format_to_string_begin<std::string>/262144 13979 ns 13979 ns 50149 bytes_per_second=17.4643Gi/s
BM_format_to_string_begin<std::string>/524288 28719 ns 28719 ns 24379 bytes_per_second=17.0019Gi/s
BM_format_to_string_begin<std::string>/1048576 57299 ns 57299 ns 12180 bytes_per_second=17.0432Gi/s
BM_format_to_string_begin<std::vector<char>>/1 46.1 ns 46.1 ns 15188343 bytes_per_second=20.6809Mi/s
BM_format_to_string_begin<std::vector<char>>/2 46.1 ns 46.1 ns 15158904 bytes_per_second=41.3318Mi/s
BM_format_to_string_begin<std::vector<char>>/4 46.1 ns 46.1 ns 15170378 bytes_per_second=82.6776Mi/s
BM_format_to_string_begin<std::vector<char>>/8 45.7 ns 45.7 ns 15315671 bytes_per_second=167.026Mi/s
BM_format_to_string_begin<std::vector<char>>/16 46.2 ns 46.2 ns 15163881 bytes_per_second=330.559Mi/s
BM_format_to_string_begin<std::vector<char>>/32 46.1 ns 46.1 ns 15201091 bytes_per_second=661.98Mi/s
BM_format_to_string_begin<std::vector<char>>/64 46.2 ns 46.2 ns 14183997 bytes_per_second=1.28927Gi/s
BM_format_to_string_begin<std::vector<char>>/128 46.7 ns 46.7 ns 14987395 bytes_per_second=2.55007Gi/s
BM_format_to_string_begin<std::vector<char>>/256 51.3 ns 51.3 ns 13898949 bytes_per_second=4.64462Gi/s
BM_format_to_string_begin<std::vector<char>>/512 50.1 ns 50.1 ns 10000000 bytes_per_second=9.52165Gi/s
BM_format_to_string_begin<std::vector<char>>/1024 59.2 ns 59.2 ns 11805042 bytes_per_second=16.105Gi/s
BM_format_to_string_begin<std::vector<char>>/2048 69.0 ns 69.0 ns 10139614 bytes_per_second=27.6266Gi/s
BM_format_to_string_begin<std::vector<char>>/4096 97.6 ns 97.6 ns 7179535 bytes_per_second=39.0938Gi/s
BM_format_to_string_begin<std::vector<char>>/8192 152 ns 152 ns 4610486 bytes_per_second=50.227Gi/s
BM_format_to_string_begin<std::vector<char>>/16384 314 ns 314 ns 2230251 bytes_per_second=48.5946Gi/s
BM_format_to_string_begin<std::vector<char>>/32768 1333 ns 1333 ns 525550 bytes_per_second=22.8868Gi/s
BM_format_to_string_begin<std::vector<char>>/65536 3760 ns 3760 ns 185821 bytes_per_second=16.2322Gi/s
BM_format_to_string_begin<std::vector<char>>/131072 6479 ns 6480 ns 107960 bytes_per_second=18.8391Gi/s
BM_format_to_string_begin<std::vector<char>>/262144 14164 ns 14164 ns 49862 bytes_per_second=17.2368Gi/s
BM_format_to_string_begin<std::vector<char>>/524288 28916 ns 28916 ns 24149 bytes_per_second=16.8861Gi/s
BM_format_to_string_begin<std::vector<char>>/1048576 57621 ns 57622 ns 12140 bytes_per_second=16.9478Gi/s
BM_format_to_string_begin<std::list<char>>/1 47.6 ns 47.6 ns 14675857 bytes_per_second=20.0271Mi/s
BM_format_to_string_begin<std::list<char>>/2 48.8 ns 48.8 ns 14331930 bytes_per_second=39.1155Mi/s
BM_format_to_string_begin<std::list<char>>/4 50.9 ns 50.9 ns 13747606 bytes_per_second=74.9309Mi/s
BM_format_to_string_begin<std::list<char>>/8 63.4 ns 63.4 ns 11065440 bytes_per_second=120.329Mi/s
BM_format_to_string_begin<std::list<char>>/16 82.4 ns 82.4 ns 8510480 bytes_per_second=185.222Mi/s
BM_format_to_string_begin<std::list<char>>/32 126 ns 126 ns 5564932 bytes_per_second=242.653Mi/s
BM_format_to_string_begin<std::list<char>>/64 211 ns 211 ns 3311820 bytes_per_second=289.214Mi/s
BM_format_to_string_begin<std::list<char>>/128 384 ns 384 ns 1825012 bytes_per_second=318.238Mi/s
BM_format_to_string_begin<std::list<char>>/256 735 ns 735 ns 951285 bytes_per_second=332.108Mi/s
BM_format_to_string_begin<std::list<char>>/512 1428 ns 1428 ns 489437 bytes_per_second=341.969Mi/s
BM_format_to_string_begin<std::list<char>>/1024 2792 ns 2792 ns 242406 bytes_per_second=349.822Mi/s
BM_format_to_string_begin<std::list<char>>/2048 5594 ns 5594 ns 124188 bytes_per_second=349.129Mi/s
BM_format_to_string_begin<std::list<char>>/4096 11163 ns 11163 ns 62794 bytes_per_second=349.936Mi/s
BM_format_to_string_begin<std::list<char>>/8192 22339 ns 22339 ns 31335 bytes_per_second=349.718Mi/s
BM_format_to_string_begin<std::list<char>>/16384 44673 ns 44674 ns 15675 bytes_per_second=349.754Mi/s
BM_format_to_string_begin<std::list<char>>/32768 89015 ns 89016 ns 7849 bytes_per_second=351.06Mi/s
BM_format_to_string_begin<std::list<char>>/65536 177988 ns 177989 ns 3938 bytes_per_second=351.145Mi/s
BM_format_to_string_begin<std::list<char>>/131072 362715 ns 362697 ns 1933 bytes_per_second=344.64Mi/s
BM_format_to_string_begin<std::list<char>>/262144 846730 ns 846685 ns 825 bytes_per_second=295.269Mi/s
BM_format_to_string_begin<std::list<char>>/524288 2018755 ns 2018721 ns 347 bytes_per_second=247.682Mi/s
BM_format_to_string_begin<std::list<char>>/1048576 4225251 ns 4225188 ns 165 bytes_per_second=236.676Mi/s
BM_format_to_string_span<char>/1 46.2 ns 46.2 ns 15156896 bytes_per_second=20.6258Mi/s
BM_format_to_string_span<char>/2 46.3 ns 46.3 ns 15114242 bytes_per_second=41.1559Mi/s
BM_format_to_string_span<char>/4 46.4 ns 46.4 ns 15089475 bytes_per_second=82.1686Mi/s
BM_format_to_string_span<char>/8 45.9 ns 45.9 ns 15249334 bytes_per_second=166.143Mi/s
BM_format_to_string_span<char>/16 46.3 ns 46.3 ns 15087074 bytes_per_second=329.233Mi/s
BM_format_to_string_span<char>/32 46.4 ns 46.4 ns 15099464 bytes_per_second=657.611Mi/s
BM_format_to_string_span<char>/64 46.4 ns 46.4 ns 14101746 bytes_per_second=1.2849Gi/s
BM_format_to_string_span<char>/128 47.0 ns 47.0 ns 14919410 bytes_per_second=2.53769Gi/s
BM_format_to_string_span<char>/256 50.8 ns 50.8 ns 13874090 bytes_per_second=4.69274Gi/s
BM_format_to_string_span<char>/512 50.5 ns 50.5 ns 13849265 bytes_per_second=9.44604Gi/s
BM_format_to_string_span<char>/1024 59.6 ns 59.6 ns 11774716 bytes_per_second=16.008Gi/s
BM_format_to_string_span<char>/2048 69.3 ns 69.3 ns 10102354 bytes_per_second=27.5137Gi/s
BM_format_to_string_span<char>/4096 98.0 ns 98.0 ns 7137947 bytes_per_second=38.9144Gi/s
BM_format_to_string_span<char>/8192 153 ns 153 ns 4585057 bytes_per_second=49.9901Gi/s
BM_format_to_string_span<char>/16384 316 ns 316 ns 2225896 bytes_per_second=48.3398Gi/s
BM_format_to_string_span<char>/32768 1339 ns 1339 ns 520365 bytes_per_second=22.7872Gi/s
BM_format_to_string_span<char>/65536 3780 ns 3780 ns 184720 bytes_per_second=16.1474Gi/s
BM_format_to_string_span<char>/131072 6557 ns 6557 ns 106444 bytes_per_second=18.6157Gi/s
BM_format_to_string_span<char>/262144 14199 ns 14199 ns 49363 bytes_per_second=17.1939Gi/s
BM_format_to_string_span<char>/524288 28833 ns 28834 ns 24254 bytes_per_second=16.9343Gi/s
BM_format_to_string_span<char>/1048576 57660 ns 57660 ns 12166 bytes_per_second=16.9365Gi/s
BM_format_to_string_pointer<char>/1 46.4 ns 46.4 ns 15070582 bytes_per_second=20.5355Mi/s
BM_format_to_string_pointer<char>/2 46.5 ns 46.5 ns 15064611 bytes_per_second=41.0239Mi/s
BM_format_to_string_pointer<char>/4 46.4 ns 46.4 ns 15080092 bytes_per_second=82.1674Mi/s
BM_format_to_string_pointer<char>/8 45.9 ns 45.9 ns 15239465 bytes_per_second=166.094Mi/s
BM_format_to_string_pointer<char>/16 46.4 ns 46.4 ns 15077440 bytes_per_second=328.884Mi/s
BM_format_to_string_pointer<char>/32 46.4 ns 46.4 ns 15070278 bytes_per_second=657.438Mi/s
BM_format_to_string_pointer<char>/64 46.4 ns 46.4 ns 14094814 bytes_per_second=1.28358Gi/s
BM_format_to_string_pointer<char>/128 46.8 ns 46.8 ns 14894522 bytes_per_second=2.54466Gi/s
BM_format_to_string_pointer<char>/256 51.2 ns 51.2 ns 13908865 bytes_per_second=4.65713Gi/s
BM_format_to_string_pointer<char>/512 50.2 ns 50.2 ns 13999036 bytes_per_second=9.5049Gi/s
BM_format_to_string_pointer<char>/1024 59.4 ns 59.4 ns 11805502 bytes_per_second=16.0611Gi/s
BM_format_to_string_pointer<char>/2048 69.1 ns 69.1 ns 10114415 bytes_per_second=27.5936Gi/s
BM_format_to_string_pointer<char>/4096 97.6 ns 97.6 ns 7154104 bytes_per_second=39.0914Gi/s
BM_format_to_string_pointer<char>/8192 151 ns 151 ns 4653492 bytes_per_second=50.6101Gi/s
BM_format_to_string_pointer<char>/16384 314 ns 314 ns 2222259 bytes_per_second=48.6129Gi/s
BM_format_to_string_pointer<char>/32768 1336 ns 13…
---
Full diff: https://github.com/llvm/llvm-project/pull/101823.diff
2 Files Affected:
- (modified) libcxx/include/__format/buffer.h (+90)
- (modified) libcxx/include/__format/format_functions.h (+2-2)
``````````diff
diff --git a/libcxx/include/__format/buffer.h b/libcxx/include/__format/buffer.h
index bfe26bfb01cb5..5337c2fe0481c 100644
--- a/libcxx/include/__format/buffer.h
+++ b/libcxx/include/__format/buffer.h
@@ -39,6 +39,7 @@
#include <__utility/exception_guard.h>
#include <__utility/move.h>
#include <cstddef>
+#include <stdexcept>
#include <string_view>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
@@ -722,6 +723,95 @@ class _LIBCPP_TEMPLATE_VIS __allocating_buffer : public __output_buffer<_CharT>
}
};
+// A buffer that directly writes to the underlying buffer.
+template <class _OutIt, __fmt_char_type _CharT>
+class _LIBCPP_TEMPLATE_VIS __direct_iterator_buffer : public __output_buffer<_CharT> {
+public:
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI explicit __direct_iterator_buffer(_OutIt __out_it)
+ : __output_buffer<_CharT>{std::__unwrap_iter(__out_it), __buffer_size, __prepare_write}, __out_it_(__out_it) {}
+
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _OutIt __out_it() && { return __out_it_ + this->__size(); }
+
+private:
+ // The function format_to expects a buffer large enough for the output. The
+ // function format_to_n has its own helper class that restricts the number of
+ // write options. So this function class can pretend to have an infinite
+ // buffer.
+ static constexpr size_t __buffer_size = -1;
+
+ _OutIt __out_it_;
+
+ _LIBCPP_HIDE_FROM_ABI static void
+ __prepare_write([[maybe_unused]] __output_buffer<_CharT>& __buffer, [[maybe_unused]] size_t __size_hint) {
+ std::__throw_length_error("__direct_iterator_buffer");
+ }
+};
+
+// A buffer that writes its output to the end of a container.
+template <class _OutIt, __fmt_char_type _CharT>
+class _LIBCPP_TEMPLATE_VIS __container_inserter_buffer : public __output_buffer<_CharT> {
+public:
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI explicit __container_inserter_buffer(_OutIt __out_it)
+ : __output_buffer<_CharT>{__buffer_, __buffer_size, __prepare_write}, __container_{__out_it.__get_container()} {}
+
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI auto __out_it() && {
+ __container_->insert(__container_->end(), __buffer_, __buffer_ + this->__size());
+ return std::back_inserter(*__container_);
+ }
+
+private:
+ typename __back_insert_iterator_container<_OutIt>::type* __container_;
+
+ // This class uses a fixed size buffer and appends the elements in
+ // __buffer_size chunks. An alternative would be to use an allocating buffer
+ // and append the output in one write operation. Benchmarking showed no
+ // performance difference.
+ static constexpr size_t __buffer_size = 256;
+ _CharT __buffer_[__buffer_size];
+
+ _LIBCPP_HIDE_FROM_ABI void __prepare_write() {
+ __container_->insert(__container_->end(), __buffer_, __buffer_ + this->__size());
+ this->__buffer_flused();
+ }
+
+ _LIBCPP_HIDE_FROM_ABI static void
+ __prepare_write(__output_buffer<_CharT>& __buffer, [[maybe_unused]] size_t __size_hint) {
+ static_cast<__container_inserter_buffer<_OutIt, _CharT>&>(__buffer).__prepare_write();
+ }
+};
+
+// A buffer that writes to an iterator.
+//
+// Unlinke the __container_inserter_buffer this class' perfomance does benefit
+// from allocating and then inserting.
+template <class _OutIt, __fmt_char_type _CharT>
+class _LIBCPP_TEMPLATE_VIS __iterator_buffer : public __allocating_buffer<_CharT> {
+public:
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI explicit __iterator_buffer(_OutIt __out_it)
+ : __allocating_buffer<_CharT>{}, __out_it_{std::move(__out_it)} {}
+
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI auto __out_it() && {
+ return std::ranges::copy(this->__view(), std::move(__out_it_)).out;
+ }
+
+private:
+ _OutIt __out_it_;
+};
+
+// Selects the type of the buffer used for the output iterator.
+template <class _OutIt, __fmt_char_type _CharT>
+class _LIBCPP_TEMPLATE_VIS __buffer_selector {
+ using _Container = __back_insert_iterator_container<_OutIt>::type;
+
+public:
+ using type =
+ conditional_t<!same_as<_Container, void>,
+ __container_inserter_buffer<_OutIt, _CharT>,
+ conditional_t<__enable_direct_output<_OutIt, _CharT>,
+ __direct_iterator_buffer<_OutIt, _CharT>,
+ __iterator_buffer<_OutIt, _CharT>>>;
+};
+
// ***** ***** ***** LLVM-19 and LLVM-20 class ***** ***** *****
// A dynamically growing buffer intended to be used for retargeting a context.
diff --git a/libcxx/include/__format/format_functions.h b/libcxx/include/__format/format_functions.h
index a5c63bd4db70f..523cd5a785a9b 100644
--- a/libcxx/include/__format/format_functions.h
+++ b/libcxx/include/__format/format_functions.h
@@ -411,7 +411,7 @@ _LIBCPP_HIDE_FROM_ABI _OutIt __vformat_to(_OutIt __out_it,
return std::__format::__vformat_to(
basic_format_parse_context{__fmt, __args.__size()}, std::__format_context_create(std::move(__out_it), __args));
else {
- __format::__format_buffer<_OutIt, _CharT> __buffer{std::move(__out_it)};
+ typename __format::__buffer_selector<_OutIt, _CharT>::type __buffer{std::move(__out_it)};
std::__format::__vformat_to(basic_format_parse_context{__fmt, __args.__size()},
std::__format_context_create(__buffer.__make_output_iterator(), __args));
return std::move(__buffer).__out_it();
@@ -544,7 +544,7 @@ _LIBCPP_HIDE_FROM_ABI _OutIt __vformat_to(
return std::__format::__vformat_to(basic_format_parse_context{__fmt, __args.__size()},
std::__format_context_create(std::move(__out_it), __args, std::move(__loc)));
else {
- __format::__format_buffer<_OutIt, _CharT> __buffer{std::move(__out_it)};
+ typename __format::__buffer_selector<_OutIt, _CharT>::type __buffer{std::move(__out_it)};
std::__format::__vformat_to(
basic_format_parse_context{__fmt, __args.__size()},
std::__format_context_create(__buffer.__make_output_iterator(), __args, std::move(__loc)));
``````````
</details>
https://github.com/llvm/llvm-project/pull/101823
More information about the llvm-branch-commits
mailing list