llvmbot wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-libcxx

Author: Mark de Wever (mordante)

<details>
<summary>Changes</summary>

This changes the __output_buffer to a new structure. Since the other formatting 
fucntions std::format_to, std::format_to_n, and std::formatted_size still use 
the old codepaths the class is in a transition state. At the end of the series 
the class should be in its final state.

write_double_comparison:

Before
----------------------------------------------------------------------------------------
Benchmark                                              Time             CPU   
Iterations
----------------------------------------------------------------------------------------
BM_sprintf                                           197 ns          196 ns     
 3550000
BM_to_string                                         218 ns          218 ns     
 3214000
BM_to_chars                                         42.4 ns         42.3 ns     
16575000
BM_to_chars_as_string                               48.2 ns         48.1 ns     
14542000
BM_format                                            175 ns          175 ns     
 4000000
BM_format_to_back_inserter&lt;std::string&gt;              175 ns          175 
ns      3995000
BM_format_to_back_inserter&lt;std::vector&lt;char&gt;&gt;        207 ns         
 206 ns      3393000
BM_format_to_back_inserter&lt;std::list&lt;char&gt;&gt;          752 ns         
 750 ns       931000
BM_format_to_iterator/&lt;std::array&gt;                   161 ns          161 
ns      4345000
BM_format_to_iterator/&lt;std::string&gt;                  161 ns          161 
ns      4344000
BM_format_to_iterator/&lt;std::vector&gt;                  162 ns          161 
ns      4344000

After
----------------------------------------------------------------------------------------
Benchmark                                              Time             CPU   
Iterations
----------------------------------------------------------------------------------------
BM_sprintf                                           197 ns          197 ns     
 3550000
BM_to_string                                         219 ns          219 ns     
 3199000
BM_to_chars                                         42.4 ns         42.4 ns     
16554000
BM_to_chars_as_string                               48.1 ns         48.1 ns     
14569000
BM_format                                            167 ns          167 ns     
 4203000
BM_format_to_back_inserter&lt;std::string&gt;              179 ns          179 
ns      3920000
BM_format_to_back_inserter&lt;std::vector&lt;char&gt;&gt;        214 ns         
 214 ns      3274000
BM_format_to_back_inserter&lt;std::list&lt;char&gt;&gt;          751 ns         
 751 ns       930000
BM_format_to_iterator/&lt;std::array&gt;                   164 ns          164 
ns      4258000
BM_format_to_iterator/&lt;std::string&gt;                  165 ns          164 
ns      4247000
BM_format_to_iterator/&lt;std::vector&gt;                  165 ns          165 
ns      4248000


Comparison
Benchmark                                                       Time            
 CPU      Time Old      Time New       CPU Old       CPU New
--------------------------------------------------------------------------------------------------------------------------------------------
BM_sprintf                                                   +0.0013         
+0.0028           197           197           196           197
BM_to_string                                                 +0.0023         
+0.0038           218           219           218           219
BM_to_chars                                                  +0.0014         
+0.0030            42            42            42            42
BM_to_chars_as_string                                        -0.0025         
-0.0010            48            48            48            48
BM_format                                                    -0.0476         
-0.0462           175           167           175           167
BM_format_to_back_inserter&lt;std::string&gt;                      +0.0190      
   +0.0205           175           179           175           179
BM_format_to_back_inserter&lt;std::vector&lt;char&gt;&gt;                
+0.0348         +0.0363           207           214           206           214
BM_format_to_back_inserter&lt;std::list&lt;char&gt;&gt;                  
-0.0013         +0.0005           752           751           750           751
BM_format_to_iterator/&lt;std::array&gt;                           +0.0188      
   +0.0203           161           164           161           164
BM_format_to_iterator/&lt;std::string&gt;                          +0.0207      
   +0.0226           161           165           161           164
BM_format_to_iterator/&lt;std::vector&gt;                          +0.0197      
   +0.0212           162           165           161           165
OVERALL_GEOMEAN                                              +0.0058         
+0.0074             0             0             0             0


write_int_comparison:

Before
----------------------------------------------------------------------------------------
Benchmark                                              Time             CPU   
Iterations
----------------------------------------------------------------------------------------
BM_sprintf                                          79.6 ns         79.5 ns     
 8739000
BM_to_string                                        14.9 ns         14.9 ns     
46713000
BM_to_chars                                         5.68 ns         5.67 ns    
120614000
BM_to_chars_as_string                               14.2 ns         14.1 ns     
49513000
BM_format                                           69.3 ns         69.2 ns     
10105000
BM_format_to_back_inserter&lt;std::string&gt;             69.2 ns         69.1 
ns     10138000
BM_format_to_back_inserter&lt;std::vector&lt;char&gt;&gt;       90.6 ns         
90.5 ns      7728000
BM_format_to_back_inserter&lt;std::list&lt;char&gt;&gt;          234 ns         
 234 ns      2986000
BM_format_to_iterator/&lt;std::array&gt;                  59.3 ns         59.3 
ns     11805000
BM_format_to_iterator/&lt;std::string&gt;                 58.7 ns         58.6 
ns     11943000
BM_format_to_iterator/&lt;std::vector&gt;                 60.1 ns         60.1 
ns     11670000

After
----------------------------------------------------------------------------------------
Benchmark                                              Time             CPU   
Iterations
----------------------------------------------------------------------------------------
BM_sprintf                                          80.2 ns         80.2 ns     
 8670000
BM_to_string                                        15.0 ns         15.0 ns     
46559000
BM_to_chars                                         4.93 ns         4.93 ns    
138016000
BM_to_chars_as_string                               15.4 ns         15.4 ns     
45415000
BM_format                                           62.1 ns         62.0 ns     
11316000
BM_format_to_back_inserter&lt;std::string&gt;             70.2 ns         70.2 
ns      9962000
BM_format_to_back_inserter&lt;std::vector&lt;char&gt;&gt;       92.8 ns         
92.8 ns      7544000
BM_format_to_back_inserter&lt;std::list&lt;char&gt;&gt;          240 ns         
 240 ns      2917000
BM_format_to_iterator/&lt;std::array&gt;                  60.5 ns         60.5 
ns     11572000
BM_format_to_iterator/&lt;std::string&gt;                 60.2 ns         60.2 
ns     11653000
BM_format_to_iterator/&lt;std::vector&gt;                 60.1 ns         60.1 
ns     11659000


Comparison
Benchmark                                                       Time            
 CPU      Time Old      Time New       CPU Old       CPU New
--------------------------------------------------------------------------------------------------------------------------------------------
BM_sprintf                                                   +0.0072         
+0.0081            80            80            80            80
BM_to_string                                                 +0.0043         
+0.0053            15            15            15            15
BM_to_chars                                                  -0.1324         
-0.1316             6             5             6             5
BM_to_chars_as_string                                        +0.0895         
+0.0906            14            15            14            15
BM_format                                                    -0.1047         
-0.1040            69            62            69            62
BM_format_to_back_inserter&lt;std::string&gt;                      +0.0148      
   +0.0157            69            70            69            70
BM_format_to_back_inserter&lt;std::vector&lt;char&gt;&gt;                
+0.0241         +0.0251            91            93            90            93
BM_format_to_back_inserter&lt;std::list&lt;char&gt;&gt;                  
+0.0222         +0.0232           234           240           234           240
BM_format_to_iterator/&lt;std::array&gt;                           +0.0196      
   +0.0205            59            60            59            60
BM_format_to_iterator/&lt;std::string&gt;                          +0.0266      
   +0.0275            59            60            59            60
BM_format_to_iterator/&lt;std::vector&gt;                          -0.0004      
   +0.0005            60            60            60            60
OVERALL_GEOMEAN                                              -0.0045         
-0.0036             0             0             0             0


write_string_comparison:

Before
---------------------------------------------------------------------------------------------------------------
Benchmark                                                                     
Time             CPU   Iterations
---------------------------------------------------------------------------------------------------------------
BM_sprintf/C string len = 6                                                4.82 
ns         4.82 ns    145548481
BM_format/C string len = 6                                                 55.1 
ns         55.1 ns     12713693
BM_format_to_back_inserter&lt;std::string&gt;/C string len = 6                  
 55.1 ns         55.1 ns     12690821
BM_format_to_back_inserter&lt;std::vector&lt;char&gt;&gt;/C string len = 6      
       71.5 ns         71.5 ns      9805550
BM_format_to_back_inserter&lt;std::deque&lt;char&gt;&gt;/C string len = 6       
        154 ns          154 ns      4536256
BM_format_to_back_inserter&lt;std::list&lt;char&gt;&gt;/C string len = 6        
        130 ns          130 ns      5348845
BM_format_to_iterator/&lt;std::array&gt; C string len = 6                       
 44.9 ns         44.9 ns     15556175
BM_format_to_iterator/&lt;std::string&gt; C string len = 6                      
 45.8 ns         45.8 ns     15290662
BM_format_to_iterator/&lt;std::vector&gt; C string len = 6                      
 44.4 ns         44.4 ns     15807704
BM_format_to_iterator/&lt;std::deque&gt; C string len = 6                       
 50.0 ns         50.0 ns     13973893
BM_format/string len = 6                                                   54.7 
ns         54.7 ns     12793406
BM_format_to_back_inserter&lt;std::string&gt;/string len = 6                    
 55.5 ns         55.5 ns     12620370
BM_format_to_back_inserter&lt;std::vector&lt;char&gt;&gt;/string len = 6        
       70.4 ns         70.4 ns      9936490
BM_format_to_back_inserter&lt;std::deque&lt;char&gt;&gt;/string len = 6         
        155 ns          155 ns      4521357
BM_format_to_back_inserter&lt;std::list&lt;char&gt;&gt;/string len = 6          
        135 ns          135 ns      5201519
BM_format_to_iterator/&lt;std::array&gt; string len = 6                         
 44.6 ns         44.6 ns     15703872
BM_format_to_iterator/&lt;std::string&gt; string len = 6                        
 45.0 ns         45.0 ns     15545182
BM_format_to_iterator/&lt;std::vector&gt; string len = 6                        
 45.0 ns         45.0 ns     15539130
BM_format_to_iterator/&lt;std::deque&gt; string len = 6                         
 50.5 ns         50.5 ns     13846916
BM_format/string_view len = 6                                              54.6 
ns         54.6 ns     12821301
BM_format_to_back_inserter&lt;std::string&gt;/string_view len = 6               
 54.6 ns         54.6 ns     12827673
BM_format_to_back_inserter&lt;std::vector&lt;char&gt;&gt;/string_view len = 6   
       69.9 ns         69.9 ns      9958365
BM_format_to_back_inserter&lt;std::deque&lt;char&gt;&gt;/string_view len = 6    
        157 ns          157 ns      4462445
BM_format_to_back_inserter&lt;std::list&lt;char&gt;&gt;/string_view len = 6     
        134 ns          134 ns      5232155
BM_format_to_iterator/&lt;std::array&gt; string_view len = 6                    
 44.2 ns         44.2 ns     15871362
BM_format_to_iterator/&lt;std::string&gt; string_view len = 6                   
 45.0 ns         45.0 ns     15582582
BM_format_to_iterator/&lt;std::vector&gt; string_view len = 6                   
 45.1 ns         45.1 ns     15539906
BM_format_to_iterator/&lt;std::deque&gt; string_view len = 6                    
 50.5 ns         50.5 ns     13896524
BM_sprintf/C string len = 60                                               4.15 
ns         4.15 ns    168165776
BM_format/C string len = 60                                                73.8 
ns         73.8 ns      9498291
BM_format_to_back_inserter&lt;std::string&gt;/C string len = 60                 
 73.6 ns         73.6 ns      9535890
BM_format_to_back_inserter&lt;std::vector&lt;char&gt;&gt;/C string len = 60     
       83.1 ns         83.1 ns      8428154
BM_format_to_back_inserter&lt;std::deque&lt;char&gt;&gt;/C string len = 60      
        281 ns          281 ns      2490093
BM_format_to_back_inserter&lt;std::list&lt;char&gt;&gt;/C string len = 60       
       1157 ns         1157 ns       605227
BM_format_to_iterator/&lt;std::array&gt; C string len = 60                      
 44.9 ns         44.9 ns     15604442
BM_format_to_iterator/&lt;std::string&gt; C string len = 60                     
 45.8 ns         45.8 ns     15272196
BM_format_to_iterator/&lt;std::vector&gt; C string len = 60                     
 44.6 ns         44.7 ns     15683193
BM_format_to_iterator/&lt;std::deque&gt; C string len = 60                      
 50.6 ns         50.6 ns     13698382
BM_format/string len = 60                                                  72.3 
ns         72.3 ns      9648955
BM_format_to_back_inserter&lt;std::string&gt;/string len = 60                   
 72.0 ns         72.0 ns      9738373
BM_format_to_back_inserter&lt;std::vector&lt;char&gt;&gt;/string len = 60       
       82.3 ns         82.3 ns      8517896
BM_format_to_back_inserter&lt;std::deque&lt;char&gt;&gt;/string len = 60        
        280 ns          280 ns      2496054
BM_format_to_back_inserter&lt;std::list&lt;char&gt;&gt;/string len = 60         
       1162 ns         1162 ns       602383
BM_format_to_iterator/&lt;std::array&gt; string len = 60                        
 44.5 ns         44.5 ns     15727799
BM_format_to_iterator/&lt;std::string&gt; string len = 60                       
 49.6 ns         49.6 ns     14096012
BM_format_to_iterator/&lt;std::vector&gt; string len = 60                       
 49.8 ns         49.8 ns     14053734
BM_format_to_iterator/&lt;std::deque&gt; string len = 60                        
 50.8 ns         50.8 ns     13801448
BM_format/string_view len = 60                                             72.5 
ns         72.5 ns      9653638
BM_format_to_back_inserter&lt;std::string&gt;/string_view len = 60              
 72.7 ns         72.7 ns      9598203
BM_format_to_back_inserter&lt;std::vector&lt;char&gt;&gt;/string_view len = 60  
       81.9 ns         81.9 ns      8522306
BM_format_to_back_inserter&lt;std::deque&lt;char&gt;&gt;/string_view len = 60   
        283 ns          283 ns      2475014
BM_format_to_back_inserter&lt;std::list&lt;char&gt;&gt;/string_view len = 60    
       1162 ns         1162 ns       600924
BM_format_to_iterator/&lt;std::array&gt; string_view len = 60                   
 44.1 ns         44.1 ns     15858951
BM_format_to_iterator/&lt;std::string&gt; string_view len = 60                  
 44.9 ns         44.9 ns     15579340
BM_format_to_iterator/&lt;std::vector&gt; string_view len = 60                  
 44.9 ns         44.9 ns     15586711
BM_format_to_iterator/&lt;std::deque&gt; string_view len = 60                   
 50.0 ns         50.0 ns     13980804
BM_sprintf/C string len = 6000                                              116 
ns          116 ns      6051541
BM_format/C string len = 6000                                              1000 
ns         1000 ns       698647
BM_format_to_back_inserter&lt;std::string&gt;/C string len = 6000               
 1002 ns         1002 ns       701440
BM_format_to_back_inserter&lt;std::vector&lt;char&gt;&gt;/C string len = 6000   
        956 ns          956 ns       727585
BM_format_to_back_inserter&lt;std::deque&lt;char&gt;&gt;/C string len = 6000    
      14898 ns        14898 ns        46994
BM_format_to_back_inserter&lt;std::list&lt;char&gt;&gt;/C string len = 6000     
     114860 ns       114859 ns         6106
BM_format_to_iterator/&lt;std::array&gt; C string len = 6000                    
  158 ns          158 ns      4425133
BM_format_to_iterator/&lt;std::string&gt; C string len = 6000                   
  161 ns          161 ns      4335471
BM_format_to_iterator/&lt;std::vector&gt; C string len = 6000                   
  157 ns          157 ns      4444174
BM_format_to_iterator/&lt;std::deque&gt; C string len = 6000                    
  445 ns          445 ns      1574120
BM_format/string len = 6000                                                 929 
ns          929 ns       753630
BM_format_to_back_inserter&lt;std::string&gt;/string len = 6000                 
  930 ns          930 ns       752888
BM_format_to_back_inserter&lt;std::vector&lt;char&gt;&gt;/string len = 6000     
        910 ns          910 ns       771111
BM_format_to_back_inserter&lt;std::deque&lt;char&gt;&gt;/string len = 6000      
      14875 ns        14876 ns        47221
BM_format_to_back_inserter&lt;std::list&lt;char&gt;&gt;/string len = 6000       
     114937 ns       114936 ns         6092
BM_format_to_iterator/&lt;std::array&gt; string len = 6000                      
  118 ns          118 ns      5963643
BM_format_to_iterator/&lt;std::string&gt; string len = 6000                     
  106 ns          106 ns      6584711
BM_format_to_iterator/&lt;std::vector&gt; string len = 6000                     
  106 ns          106 ns      6583118
BM_format_to_iterator/&lt;std::deque&gt; string len = 6000                      
  391 ns          391 ns      1790538
BM_format/string_view len = 6000                                            935 
ns          935 ns       744348
BM_format_to_back_inserter&lt;std::string&gt;/string_view len = 6000            
  934 ns          934 ns       742039
BM_format_to_back_inserter&lt;std::vector&lt;char&gt;&gt;/string_view len = 
6000        895 ns          895 ns       783527
BM_format_to_back_inserter&lt;std::deque&lt;char&gt;&gt;/string_view len = 6000 
      14864 ns        14865 ns        47122
BM_format_to_back_inserter&lt;std::list&lt;char&gt;&gt;/string_view len = 6000  
     115042 ns       115044 ns         6091
BM_format_to_iterator/&lt;std::array&gt; string_view len = 6000                 
  115 ns          115 ns      6070197
BM_format_to_iterator/&lt;std::string&gt; string_view len = 6000                
  116 ns          116 ns      6035109
BM_format_to_iterator/&lt;std::vector&gt; string_view len = 6000                
  115 ns          115 ns      6067683
BM_format_to_iterator/&lt;std::deque&gt; string_view len = 6000                 
  387 ns          387 ns      1803466

After
---------------------------------------------------------------------------------------------------------------
Benchmark                                                                     
Time             CPU   Iterations
---------------------------------------------------------------------------------------------------------------
BM_sprintf/C string len = 6                                                3.56 
ns         3.56 ns    196337806
BM_format/C string len = 6                                                 49.1 
ns         49.1 ns     14241174
BM_format_to_back_inserter&lt;std::string&gt;/C string len = 6                  
 56.8 ns         56.8 ns     12341483
BM_format_to_back_inserter&lt;std::vector&lt;char&gt;&gt;/C string len = 6      
       72.9 ns         72.9 ns      9610864
BM_format_to_back_inserter&lt;std::deque&lt;char&gt;&gt;/C string len = 6       
        155 ns          155 ns      4528719
BM_format_to_back_inserter&lt;std::list&lt;char&gt;&gt;/C string len = 6        
        137 ns          137 ns      5103340
BM_format_to_iterator/&lt;std::array&gt; C string len = 6                       
 46.4 ns         46.4 ns     15081626
BM_format_to_iterator/&lt;std::string&gt; C string len = 6                      
 47.0 ns         47.0 ns     14893458
BM_format_to_iterator/&lt;std::vector&gt; C string len = 6                      
 45.9 ns         45.9 ns     15243762
BM_format_to_iterator/&lt;std::deque&gt; C string len = 6                       
 52.6 ns         52.6 ns     13323560
BM_format/string len = 6                                                   49.3 
ns         49.3 ns     14181485
BM_format_to_back_inserter&lt;std::string&gt;/string len = 6                    
 55.4 ns         55.4 ns     12644078
BM_format_to_back_inserter&lt;std::vector&lt;char&gt;&gt;/string len = 6        
       72.7 ns         72.7 ns      9618696
BM_format_to_back_inserter&lt;std::deque&lt;char&gt;&gt;/string len = 6         
        154 ns          154 ns      4540873
BM_format_to_back_inserter&lt;std::list&lt;char&gt;&gt;/string len = 6          
        134 ns          134 ns      5220153
BM_format_to_iterator/&lt;std::array&gt; string len = 6                         
 46.5 ns         46.5 ns     15064445
BM_format_to_iterator/&lt;std::string&gt; string len = 6                        
 47.3 ns         47.3 ns     14786851
BM_format_to_iterator/&lt;std::vector&gt; string len = 6                        
 46.5 ns         46.5 ns     15069381
BM_format_to_iterator/&lt;std::deque&gt; string len = 6                         
 52.9 ns         52.9 ns     13207437
BM_format/string_view len = 6                                              47.6 
ns         47.6 ns     14688449
BM_format_to_back_inserter&lt;std::string&gt;/string_view len = 6               
 56.1 ns         56.1 ns     12514239
BM_format_to_back_inserter&lt;std::vector&lt;char&gt;&gt;/string_view len = 6   
       72.0 ns         72.0 ns      9705591
BM_format_to_back_inserter&lt;std::deque&lt;char&gt;&gt;/string_view len = 6    
        152 ns          152 ns      4607470
BM_format_to_back_inserter&lt;std::list&lt;char&gt;&gt;/string_view len = 6     
        134 ns          134 ns      5233005
BM_format_to_iterator/&lt;std::array&gt; string_view len = 6                    
 46.0 ns         46.0 ns     15205542
BM_format_to_iterator/&lt;std::string&gt; string_view len = 6                   
 46.5 ns         46.5 ns     15067775
BM_format_to_iterator/&lt;std::vector&gt; string_view len = 6                   
 46.5 ns         46.5 ns     15057288
BM_format_to_iterator/&lt;std::deque&gt; string_view len = 6                    
 51.8 ns         51.8 ns     13564649
BM_sprintf/C string len = 60                                               4.83 
ns         4.83 ns    145020116
BM_format/C string len = 60                                                72.3 
ns         72.3 ns      9665555
BM_format_to_back_inserter&lt;std::string&gt;/C string len = 60                 
 85.0 ns         85.0 ns      8249050
BM_format_to_back_inserter&lt;std::vector&lt;char&gt;&gt;/C string len = 60     
       94.7 ns         94.7 ns      7398143
BM_format_to_back_inserter&lt;std::deque&lt;char&gt;&gt;/C string len = 60      
        286 ns          286 ns      2452225
BM_format_to_back_inserter&lt;std::list&lt;char&gt;&gt;/C string len = 60       
       1179 ns         1179 ns       595011
BM_format_to_iterator/&lt;std::array&gt; C string len = 60                      
 46.1 ns         46.1 ns     15157525
BM_format_to_iterator/&lt;std::string&gt; C string len = 60                     
 47.0 ns         47.0 ns     14899863
BM_format_to_iterator/&lt;std::vector&gt; C string len = 60                     
 45.8 ns         45.8 ns     15272542
BM_format_to_iterator/&lt;std::deque&gt; C string len = 60                      
 58.7 ns         58.7 ns     11958910
BM_format/string len = 60                                                  61.7 
ns         61.7 ns     11308865
BM_format_to_back_inserter&lt;std::string&gt;/string len = 60                   
 74.2 ns         74.2 ns      9401855
BM_format_to_back_inserter&lt;std::vector&lt;char&gt;&gt;/string len = 60       
       86.6 ns         86.6 ns      8079197
BM_format_to_back_inserter&lt;std::deque&lt;char&gt;&gt;/string len = 60        
        278 ns          278 ns      2519254
BM_format_to_back_inserter&lt;std::list&lt;char&gt;&gt;/string len = 60         
       1169 ns         1170 ns       597703
BM_format_to_iterator/&lt;std::array&gt; string len = 60                        
 46.4 ns         46.4 ns     15074759
BM_format_to_iterator/&lt;std::string&gt; string len = 60                       
 47.3 ns         47.3 ns     14801107
BM_format_to_iterator/&lt;std::vector&gt; string len = 60                       
 46.3 ns         46.4 ns     15085548
BM_format_to_iterator/&lt;std::deque&gt; string len = 60                        
 52.2 ns         52.2 ns     13331015
BM_format/string_view len = 60                                             65.0 
ns         65.0 ns     10756847
BM_format_to_back_inserter&lt;std::string&gt;/string_view len = 60              
 78.5 ns         78.5 ns      9051370
BM_format_to_back_inserter&lt;std::vector&lt;char&gt;&gt;/string_view len = 60  
       87.9 ns         87.9 ns      7946825
BM_format_to_back_inserter&lt;std::deque&lt;char&gt;&gt;/string_view len = 60   
        280 ns          280 ns      2505999
BM_format_to_back_inserter&lt;std::list&lt;char&gt;&gt;/string_view len = 60    
       1174 ns         1174 ns       594829
BM_format_to_iterator/&lt;std::array&gt; string_view len = 60                   
 46.3 ns         46.3 ns     15149785
BM_format_to_iterator/&lt;std::string&gt; string_view len = 60                  
 46.7 ns         46.7 ns     15002678
BM_format_to_iterator/&lt;std::vector&gt; string_view len = 60                  
 46.7 ns         46.7 ns     14996445
BM_format_to_iterator/&lt;std::deque&gt; string_view len = 60                   
 52.6 ns         52.6 ns     13255470
BM_sprintf/C string len = 6000                                             77.1 
ns         77.1 ns      9099121
BM_format/C string len = 6000                                               350 
ns          350 ns      2013049
BM_format_to_back_inserter&lt;std::string&gt;/C string len = 6000               
  992 ns          992 ns       709093
BM_format_to_back_inserter&lt;std::vector&lt;char&gt;&gt;/C string len = 6000   
       1016 ns         1016 ns       694784
BM_format_to_back_inserter&lt;std::deque&lt;char&gt;&gt;/C string len = 6000    
      15158 ns        15159 ns        46125
BM_format_to_back_inserter&lt;std::list&lt;char&gt;&gt;/C string len = 6000     
     115703 ns       115705 ns         6055
BM_format_to_iterator/&lt;std::array&gt; C string len = 6000                    
  166 ns          166 ns      4224749
BM_format_to_iterator/&lt;std::string&gt; C string len = 6000                   
  153 ns          153 ns      4573034
BM_format_to_iterator/&lt;std::vector&gt; C string len = 6000                   
  150 ns          150 ns      4678898
BM_format_to_iterator/&lt;std::deque&gt; C string len = 6000                    
  465 ns          465 ns      1506323
BM_format/string len = 6000                                                 281 
ns          281 ns      2462572
BM_format_to_back_inserter&lt;std::string&gt;/string len = 6000                 
  935 ns          935 ns       745376
BM_format_to_back_inserter&lt;std::vector&lt;char&gt;&gt;/string len = 6000     
        939 ns          939 ns       747498
BM_format_to_back_inserter&lt;std::deque&lt;char&gt;&gt;/string len = 6000      
      15069 ns        15069 ns        46429
BM_format_to_back_inserter&lt;std::list&lt;char&gt;&gt;/string len = 6000       
     115537 ns       115539 ns         6063
BM_format_to_iterator/&lt;std::array&gt; string len = 6000                      
  120 ns          120 ns      5849159
BM_format_to_iterator/&lt;std::string&gt; string len = 6000                     
  108 ns          108 ns      6482306
BM_format_to_iterator/&lt;std::vector&gt; string len = 6000                     
  107 ns          107 ns      6547915
BM_format_to_iterator/&lt;std::deque&gt; string len = 6000                      
  397 ns          397 ns      1763729
BM_format/string_view len = 6000                                            282 
ns          282 ns      2490133
BM_format_to_back_inserter&lt;std::string&gt;/string_view len = 6000            
  927 ns          927 ns       750931
BM_format_to_back_inserter&lt;std::vector&lt;char&gt;&gt;/string_view len = 
6000        946 ns          946 ns       735544
BM_format_to_back_inserter&lt;std::deque&lt;char&gt;&gt;/string_view len = 6000 
      15028 ns        15029 ns        46612
BM_format_to_back_inserter&lt;std::list&lt;char&gt;&gt;/string_view len = 6000  
     115153 ns       115153 ns         6057
BM_format_to_iterator/&lt;std::array&gt; string_view len = 6000                 
  122 ns          122 ns      5753940
BM_format_to_iterator/&lt;std::string&gt; string_view len = 6000                
  108 ns          108 ns      6507555
BM_format_to_iterator/&lt;std::vector&gt; string_view len = 6000                
  107 ns          107 ns      6510450
BM_format_to_iterator/&lt;std::deque&gt; string_view len = 6000                 
  398 ns          398 ns      1762517

Comparison
Benchmark                                                                       
       Time             CPU      Time Old      Time New       CPU Old       CPU 
New
-------------------------------------------------------------------------------------------------------------------------------------------------------------------
BM_sprintf/C string len = 6                                                     
    -0.2599         -0.2599             5             4             5           
  4
BM_format/C string len = 6                                                      
    -0.1094         -0.1095            55            49            55           
 49
BM_format_to_back_inserter&lt;std::string&gt;/C string len = 6                  
          +0.0316         +0.0316            55            57            55     
       57
BM_format_to_back_inserter&lt;std::vector&lt;char&gt;&gt;/C string len = 6      
                +0.0204         +0.0204            71            73            
71            73
BM_format_to_back_inserter&lt;std::deque&lt;char&gt;&gt;/C string len = 6       
                +0.0023         +0.0023           154           155           
154           155
BM_format_to_back_inserter&lt;std::list&lt;char&gt;&gt;/C string len = 6        
                +0.0521         +0.0520           130           137           
130           137
BM_format_to_iterator/&lt;std::array&gt; C string len = 6                       
          +0.0317         +0.0317            45            46            45     
       46
BM_format_to_iterator/&lt;std::string&gt; C string len = 6                      
          +0.0265         +0.0265            46            47            46     
       47
BM_format_to_iterator/&lt;std::vector&gt; C string len = 6                      
          +0.0345         +0.0345            44            46            44     
       46
BM_format_to_iterator/&lt;std::deque&gt; C string len = 6                       
          +0.0511         +0.0511            50            53            50     
       53
BM_format/string len = 6                                                        
    -0.0981         -0.0981            55            49            55           
 49
BM_format_to_back_inserter&lt;std::string&gt;/string len = 6                    
          -0.0028         -0.0028            56            55            56     
       55
BM_format_to_back_inserter&lt;std::vector&lt;char&gt;&gt;/string len = 6        
                +0.0331         +0.0331            70            73            
70            73
BM_format_to_back_inserter&lt;std::deque&lt;char&gt;&gt;/string len = 6         
                -0.0040         -0.0040           155           154           
155           154
BM_format_to_back_inserter&lt;std::list&lt;char&gt;&gt;/string len = 6          
                -0.0019         -0.0019           135           134           
135           134
BM_format_to_iterator/&lt;std::array&gt; string len = 6                         
          +0.0427         +0.0427            45            46            45     
       46
BM_format_to_iterator/&lt;std::string&gt; string len = 6                        
          +0.0515         +0.0515            45            47            45     
       47
BM_format_to_iterator/&lt;std::vector&gt; string len = 6                        
          +0.0316         +0.0316            45            46            45     
       46
BM_format_to_iterator/&lt;std::deque&gt; string len = 6                         
          +0.0475         +0.0475            51            53            51     
       53
BM_format/string_view len = 6                                                   
    -0.1267         -0.1267            55            48            55           
 48
BM_format_to_back_inserter&lt;std::string&gt;/string_view len = 6               
          +0.0283         +0.0283            55            56            55     
       56
BM_format_to_back_inserter&lt;std::vector&lt;char&gt;&gt;/string_view len = 6   
                +0.0291         +0.0291            70            72            
70            72
BM_format_to_back_inserter&lt;std::deque&lt;char&gt;&gt;/string_view len = 6    
                -0.0305         -0.0306           157           152           
157           152
BM_format_to_back_inserter&lt;std::list&lt;char&gt;&gt;/string_view len = 6     
                -0.0012         -0.0012           134           134           
134           134
BM_format_to_iterator/&lt;std::array&gt; string_view len = 6                    
          +0.0426         +0.0426            44            46            44     
       46
BM_format_to_iterator/&lt;std::string&gt; string_view len = 6                   
          +0.0322         +0.0322            45            46            45     
       46
BM_format_to_iterator/&lt;std::vector&gt; string_view len = 6                   
          +0.0309         +0.0309            45            46            45     
       46
BM_format_to_iterator/&lt;std::deque&gt; string_view len = 6                    
          +0.0248         +0.0248            51            52            51     
       52
BM_sprintf/C string len = 60                                                    
    +0.1633         +0.1633             4             5             4           
  5
BM_format/C string len = 60                                                     
    -0.0203         -0.0203            74            72            74           
 72
BM_format_to_back_inserter&lt;std::string&gt;/C string len = 60                 
          +0.1548         +0.1548            74            85            74     
       85
BM_format_to_back_inserter&lt;std::vector&lt;char&gt;&gt;/C string len = 60     
                +0.1395         +0.1395            83            95            
83            95
BM_format_to_back_inserter&lt;std::deque&lt;char&gt;&gt;/C string len = 60      
                +0.0157         +0.0157           281           286           
281           286
BM_format_to_back_inserter&lt;std::list&lt;char&gt;&gt;/C string len = 60       
                +0.0191         +0.0191          1157          1179          
1157          1179
BM_format_to_iterator/&lt;std::array&gt; C string len = 60                      
          +0.0283         +0.0283            45            46            45     
       46
BM_format_to_iterator/&lt;std::string&gt; C string len = 60                     
          +0.0251         +0.0252            46            47            46     
       47
BM_format_to_iterator/&lt;std::vector&gt; C string len = 60                     
          +0.0263         +0.0263            45            46            45     
       46
BM_format_to_iterator/&lt;std::deque&gt; C string len = 60                      
          +0.1592         +0.1591            51            59            51     
       59
BM_format/string len = 60                                                       
    -0.1466         -0.1466            72            62            72           
 62
BM_format_to_back_inserter&lt;std::string&gt;/string len = 60                   
          +0.0299         +0.0299            72            74            72     
       74
BM_format_to_back_inserter&lt;std::vector&lt;char&gt;&gt;/string len = 60       
                +0.0522         +0.0522            82            87            
82            87
BM_format_to_back_inserter&lt;std::deque&lt;char&gt;&gt;/string len = 60        
                -0.0099         -0.0099           280           278           
280           278
BM_format_to_back_inserter&lt;std::list&lt;char&gt;&gt;/string len = 60         
                +0.0062         +0.0062          1162          1169          
1162          1170
BM_format_to_iterator/&lt;std::array&gt; string len = 60                        
          +0.0430         +0.0430            45            46            45     
       46
BM_format_to_iterator/&lt;std::string&gt; string len = 60                       
          -0.0466         -0.0466            50            47            50     
       47
BM_format_to_iterator/&lt;std::vector&gt; string len = 60                       
          -0.0693         -0.0693            50            46            50     
       46
BM_format_to_iterator/&lt;std::deque&gt; string len = 60                        
          +0.0275         +0.0275            51            52            51     
       52
BM_format/string_view len = 60                                                  
    -0.1034         -0.1034            73            65            73           
 65
BM_format_to_back_inserter&lt;std::string&gt;/string_view len = 60              
          +0.0790         +0.0790            73            78            73     
       78
BM_format_to_back_inserter&lt;std::vector&lt;char&gt;&gt;/string_view len = 60  
                +0.0735         +0.0735            82            88            
82            88
BM_format_to_back_inserter&lt;std::deque&lt;char&gt;&gt;/string_view len = 60   
                -0.0103         -0.0104           283           280           
283           280
BM_format_to_back_inserter&lt;std::list&lt;char&gt;&gt;/string_view len = 60    
                +0.0101         +0.0101          1162          1174          
1162          1174
BM_format_to_iterator/&lt;std::array&gt; string_view len = 60                   
          +0.0484         +0.0484            44            46            44     
       46
BM_format_to_iterator/&lt;std::string&gt; string_view len = 60                  
          +0.0387         +0.0387            45            47            45     
       47
BM_format_to_iterator/&lt;std::vector&gt; string_view len = 60                  
          +0.0402         +0.0402            45            47            45     
       47
BM_format_to_iterator/&lt;std::deque&gt; string_view len = 60                   
          +0.0508         +0.0508            50            53            50     
       53
BM_sprintf/C string len = 6000                                                  
    -0.3337         -0.3337           116            77           116           
 77
BM_format/C string len = 6000                                                   
    -0.6500         -0.6500          1000           350          1000           
350
BM_format_to_back_inserter&lt;std::string&gt;/C string len = 6000               
          -0.0104         -0.0105          1002           992          1002     
      992
BM_format_to_back_inserter&lt;std::vector&lt;char&gt;&gt;/C string len = 6000   
                +0.0630         +0.0630           956          1016           
956          1016
BM_format_to_back_inserter&lt;std::deque&lt;char&gt;&gt;/C string len = 6000    
                +0.0175         +0.0175         14898         15158         
14898         15159
BM_format_to_back_inserter&lt;std::list&lt;char&gt;&gt;/C string len = 6000     
                +0.0073         +0.0074        114860        115703        
114859        115705
BM_format_to_iterator/&lt;std::array&gt; C string len = 6000                    
          +0.0504         +0.0504           158           166           158     
      166
BM_format_to_iterator/&lt;std::string&gt; C string len = 6000                   
          -0.0486         -0.0486           161           153           161     
      153
BM_format_to_iterator/&lt;std::vector&gt; C string len = 6000                   
          -0.0483         -0.0483           157           150           157     
      150
BM_format_to_iterator/&lt;std::deque&gt; C string len = 6000                    
          +0.0459         +0.0459           445           465           445     
      465
BM_format/string len = 6000                                                     
    -0.6975         -0.6975           929           281           929           
281
BM_format_to_back_inserter&lt;std::string&gt;/string len = 6000                 
          +0.0050         +0.0050           930           935           930     
      935
BM_format_to_back_inserter&lt;std::vector&lt;char&gt;&gt;/string len = 6000     
                +0.0321         +0.0322           910           939           
910           939
BM_format_to_back_inserter&lt;std::deque&lt;char&gt;&gt;/string len = 6000      
                +0.0130         +0.0130         14875         15069         
14876         15069
BM_format_to_back_inserter&lt;std::list&lt;char&gt;&gt;/string len = 6000       
                +0.0052         +0.0052        114937        115537        
114936        115539
BM_format_to_iterator/&lt;std::array&gt; string len = 6000                      
          +0.0211         +0.0211           118           120           118     
      120
BM_format_to_iterator/&lt;std::string&gt; string len = 6000                     
          +0.0146         +0.0146           106           108           106     
      108
BM_format_to_iterator/&lt;std::vector&gt; string len = 6000                     
          +0.0048         +0.0048           106           107           106     
      107
BM_format_to_iterator/&lt;std::deque&gt; string len = 6000                      
          +0.0150         +0.0150           391           397           391     
      397
BM_format/string_view len = 6000                                                
    -0.6989         -0.6989           935           282           935           
282
BM_format_to_back_inserter&lt;std::string&gt;/string_view len = 6000            
          -0.0083         -0.0083           934           927           934     
      927
BM_format_to_back_inserter&lt;std::vector&lt;char&gt;&gt;/string_view len = 
6000                +0.0566         +0.0566           895           946         
  895           946
BM_format_to_back_inserter&lt;std::deque&lt;char&gt;&gt;/string_view len = 6000 
                +0.0111         +0.0110         14864         15028         
14865         15029
BM_format_to_back_inserter&lt;std::list&lt;char&gt;&gt;/string_view len = 6000  
                +0.0010         +0.0009        115042        115153        
115044        115153
BM_format_to_iterator/&lt;std::array&gt; string_view len = 6000                 
          +0.0560         +0.0560           115           122           115     
      122
BM_format_to_iterator/&lt;std::string&gt; string_view len = 6000                
          -0.0693         -0.0693           116           108           116     
      108
BM_format_to_iterator/&lt;std::vector&gt; string_view len = 6000                
          -0.0703         -0.0703           115           107           115     
      107
BM_format_to_iterator/&lt;std::deque&gt; string_view len = 6000                 
          +0.0271         +0.0271           387           398           387     
      398
OVERALL_GEOMEAN                                                                 
    -0.0350         -0.0350             0             0             0           
  0


format:
Before
--------------------------------------------------------------------------------------------
Benchmark                                  Time             CPU   Iterations 
UserCounters...
--------------------------------------------------------------------------------------------
BM_format_string&lt;char&gt;/1                55.5 ns         55.5 ns     
12463288 bytes_per_second=17.187Mi/s
BM_format_string&lt;char&gt;/2                27.6 ns         27.6 ns     
25421994 bytes_per_second=69.1874Mi/s
BM_format_string&lt;char&gt;/4                14.0 ns         14.0 ns     
49785656 bytes_per_second=271.524Mi/s
BM_format_string&lt;char&gt;/8                7.07 ns         7.07 ns     
99247048 bytes_per_second=1.05444Gi/s
BM_format_string&lt;char&gt;/16               3.53 ns         3.53 ns    
198072224 bytes_per_second=4.21726Gi/s
BM_format_string&lt;char&gt;/32               2.31 ns         2.31 ns    
302771136 bytes_per_second=12.9138Gi/s
BM_format_string&lt;char&gt;/64               1.15 ns         1.15 ns    
606646976 bytes_per_second=51.7527Gi/s
BM_format_string&lt;char&gt;/128             0.597 ns        0.597 ns   
1172263936 bytes_per_second=199.688Gi/s
BM_format_string&lt;char&gt;/256             0.327 ns        0.327 ns   
2148927744 bytes_per_second=728.678Gi/s
BM_format_string&lt;char&gt;/512             0.248 ns        0.248 ns   
2821635584 bytes_per_second=1.8779Ti/s
BM_format_string&lt;char&gt;/1024            0.203 ns        0.203 ns   
3433579520 bytes_per_second=4.57798Ti/s
BM_format_string&lt;char&gt;/2048            0.164 ns        0.164 ns   
4277524480 bytes_per_second=11.3793Ti/s
BM_format_string&lt;char&gt;/4096            0.137 ns        0.137 ns   
5122269184 bytes_per_second=27.2589Ti/s
BM_format_string&lt;char&gt;/8192            0.126 ns        0.126 ns   
5564243968 bytes_per_second=59.2812Ti/s
BM_format_string&lt;char&gt;/16384           0.136 ns        0.136 ns   
5153013760 bytes_per_second=109.492Ti/s
BM_format_string&lt;char&gt;/32768           0.135 ns        0.135 ns   
5165088768 bytes_per_second=219.985Ti/s
BM_format_string&lt;char&gt;/65536           0.243 ns        0.242 ns   
2930180096 bytes_per_second=246.57Ti/s
BM_format_string&lt;char&gt;/131072          0.490 ns        0.489 ns   
1437990912 bytes_per_second=243.75Ti/s
BM_format_string&lt;char&gt;/262144          0.593 ns        0.592 ns   
1183055872 bytes_per_second=402.931Ti/s
BM_format_string&lt;char&gt;/524288          0.643 ns        0.641 ns   
1092616192 bytes_per_second=743.445Ti/s
BM_format_string&lt;char&gt;/1048576         0.669 ns        0.668 ns   
1045430272 bytes_per_second=1.39478Pi/s
BM_format_string&lt;wchar_t&gt;/1             56.0 ns         55.9 ns     
12511543 bytes_per_second=68.2628Mi/s
BM_format_string&lt;wchar_t&gt;/2             28.0 ns         27.9 ns     
25062366 bytes_per_second=273.519Mi/s
BM_format_string&lt;wchar_t&gt;/4             14.0 ns         14.0 ns     
50257068 bytes_per_second=1.06742Gi/s
BM_format_string&lt;wchar_t&gt;/8             9.24 ns         9.21 ns     
76118616 bytes_per_second=3.23473Gi/s
BM_format_string&lt;wchar_t&gt;/16            4.66 ns         4.65 ns    
151420352 bytes_per_second=12.8261Gi/s
BM_format_string&lt;wchar_t&gt;/32            2.35 ns         2.35 ns    
298417600 bytes_per_second=50.7972Gi/s
BM_format_string&lt;wchar_t&gt;/64            1.35 ns         1.34 ns    
521608704 bytes_per_second=177.502Gi/s
BM_format_string&lt;wchar_t&gt;/128           1.03 ns         1.03 ns    
680946304 bytes_per_second=463.91Gi/s
BM_format_string&lt;wchar_t&gt;/256          0.849 ns        0.847 ns    
825871104 bytes_per_second=1.09901Ti/s
BM_format_string&lt;wchar_t&gt;/512          0.681 ns        0.679 ns   
1033245696 bytes_per_second=2.74383Ti/s
BM_format_string&lt;wchar_t&gt;/1024         0.576 ns        0.575 ns   
1219777536 bytes_per_second=6.48343Ti/s
BM_format_string&lt;wchar_t&gt;/2048         0.515 ns        0.514 ns   
1361629184 bytes_per_second=14.4881Ti/s
BM_format_string&lt;wchar_t&gt;/4096         0.546 ns        0.545 ns   
1285427200 bytes_per_second=27.3342Ti/s
BM_format_string&lt;wchar_t&gt;/8192         0.550 ns        0.548 ns   
1277042688 bytes_per_second=54.3343Ti/s
BM_format_string&lt;wchar_t&gt;/16384        0.583 ns        0.581 ns   
1203879936 bytes_per_second=102.544Ti/s
BM_format_string&lt;wchar_t&gt;/32768        0.640 ns        0.638 ns   
1095139328 bytes_per_second=186.82Ti/s
BM_format_string&lt;wchar_t&gt;/65536        0.642 ns        0.640 ns   
1093337088 bytes_per_second=372.283Ti/s
BM_format_string&lt;wchar_t&gt;/131072       0.655 ns        0.654 ns   
1070596096 bytes_per_second=729.428Ti/s
BM_format_string&lt;wchar_t&gt;/262144        2.68 ns         2.67 ns    
262406144 bytes_per_second=357.446Ti/s
BM_format_string&lt;wchar_t&gt;/524288        2.13 ns         2.13 ns    
330301440 bytes_per_second=897.574Ti/s
BM_format_string&lt;wchar_t&gt;/1048576       2.44 ns         2.43 ns    
288358400 bytes_per_second=1.53149Pi/s

After
--------------------------------------------------------------------------------------------
Benchmark                                  Time             CPU   Iterations 
UserCounters...
--------------------------------------------------------------------------------------------
BM_format_string&lt;char&gt;/1                49.3 ns         49.1 ns     
14230742 bytes_per_second=19.4054Mi/s
BM_format_string&lt;char&gt;/2                24.8 ns         24.8 ns     
28253114 bytes_per_second=77.0465Mi/s
BM_format_string&lt;char&gt;/4                12.4 ns         12.4 ns     
56381440 bytes_per_second=307.462Mi/s
BM_format_string&lt;char&gt;/8                6.23 ns         6.21 ns    
112951232 bytes_per_second=1.19924Gi/s
BM_format_string&lt;char&gt;/16               3.10 ns         3.09 ns    
225822496 bytes_per_second=4.81566Gi/s
BM_format_string&lt;char&gt;/32               1.98 ns         1.98 ns    
354208192 bytes_per_second=15.0825Gi/s
BM_format_string&lt;char&gt;/64              0.990 ns        0.987 ns    
714296384 bytes_per_second=60.3689Gi/s
BM_format_string&lt;char&gt;/128             0.504 ns        0.503 ns   
1399988480 bytes_per_second=237.144Gi/s
BM_format_string&lt;char&gt;/256             0.335 ns        0.334 ns   
2084828928 bytes_per_second=712.859Gi/s
BM_format_string&lt;char&gt;/512             0.187 ns        0.186 ns   
3760082432 bytes_per_second=2.50102Ti/s
BM_format_string&lt;char&gt;/1024            0.109 ns        0.108 ns   
6455339008 bytes_per_second=8.59552Ti/s
BM_format_string&lt;char&gt;/2048            0.080 ns        0.080 ns   
8754006016 bytes_per_second=23.2731Ti/s
BM_format_string&lt;char&gt;/4096            0.051 ns        0.051 ns   
13786701824 bytes_per_second=73.4088Ti/s
BM_format_string&lt;char&gt;/8192            0.042 ns        0.042 ns   
16851435520 bytes_per_second=178.737Ti/s
BM_format_string&lt;char&gt;/16384           0.122 ns        0.122 ns   
5746589696 bytes_per_second=122.029Ti/s
BM_format_string&lt;char&gt;/32768           0.107 ns        0.106 ns   
6571687936 bytes_per_second=280.122Ti/s
BM_format_string&lt;char&gt;/65536           0.102 ns        0.102 ns   
6876626944 bytes_per_second=584.381Ti/s
BM_format_string&lt;char&gt;/131072          0.106 ns        0.105 ns   
6643122176 bytes_per_second=1.10413Pi/s
BM_format_string&lt;char&gt;/262144          0.589 ns        0.587 ns   
1189609472 bytes_per_second=406.438Ti/s
BM_format_string&lt;char&gt;/524288          0.644 ns        0.642 ns   
1088946176 bytes_per_second=743.064Ti/s
BM_format_string&lt;char&gt;/1048576         0.672 ns        0.670 ns   
1039138816 bytes_per_second=1.38968Pi/s
BM_format_string&lt;wchar_t&gt;/1             48.7 ns         48.6 ns     
14423178 bytes_per_second=78.5263Mi/s
BM_format_string&lt;wchar_t&gt;/2             24.4 ns         24.3 ns     
28831748 bytes_per_second=313.869Mi/s
BM_format_string&lt;wchar_t&gt;/4             12.2 ns         12.2 ns     
57661220 bytes_per_second=1.2253Gi/s
BM_format_string&lt;wchar_t&gt;/8             7.81 ns         7.79 ns     
89887592 bytes_per_second=3.82675Gi/s
BM_format_string&lt;wchar_t&gt;/16            3.88 ns         3.87 ns    
180450176 bytes_per_second=15.418Gi/s
BM_format_string&lt;wchar_t&gt;/32            1.98 ns         1.98 ns    
354046112 bytes_per_second=60.3262Gi/s
BM_format_string&lt;wchar_t&gt;/64            1.02 ns         1.01 ns    
689511680 bytes_per_second=234.906Gi/s
BM_format_string&lt;wchar_t&gt;/128          0.577 ns        0.576 ns   
1215361408 bytes_per_second=828.297Gi/s
BM_format_string&lt;wchar_t&gt;/256          0.804 ns        0.802 ns    
872249088 bytes_per_second=1.16111Ti/s
BM_format_string&lt;wchar_t&gt;/512          0.642 ns        0.641 ns   
1093858304 bytes_per_second=2.90766Ti/s
BM_format_string&lt;wchar_t&gt;/1024         0.517 ns        0.516 ns   
1354798080 bytes_per_second=7.21845Ti/s
BM_format_string&lt;wchar_t&gt;/2048         0.469 ns        0.467 ns   
1491910656 bytes_per_second=15.9386Ti/s
BM_format_string&lt;wchar_t&gt;/4096         0.794 ns        0.792 ns    
883822592 bytes_per_second=18.8156Ti/s
BM_format_string&lt;wchar_t&gt;/8192         0.722 ns        0.720 ns    
971718656 bytes_per_second=41.3996Ti/s
BM_format_string&lt;wchar_t&gt;/16384        0.703 ns        0.701 ns    
998031360 bytes_per_second=85.0369Ti/s
BM_format_string&lt;wchar_t&gt;/32768        0.724 ns        0.720 ns    
971538432 bytes_per_second=165.467Ti/s
BM_format_string&lt;wchar_t&gt;/65536        0.745 ns        0.744 ns    
941228032 bytes_per_second=320.665Ti/s
BM_format_string&lt;wchar_t&gt;/131072       0.742 ns        0.740 ns    
945422336 bytes_per_second=644.032Ti/s
BM_format_string&lt;wchar_t&gt;/262144        2.99 ns         2.98 ns    
234881024 bytes_per_second=319.75Ti/s
BM_format_string&lt;wchar_t&gt;/524288        3.31 ns         3.30 ns    
212860928 bytes_per_second=578.085Ti/s
BM_format_string&lt;wchar_t&gt;/1048576       2.69 ns         2.68 ns    
260046848 bytes_per_second=1.39081Pi/s

Comparison
Benchmark                                           Time             CPU      
Time Old      Time New       CPU Old       CPU New
--------------------------------------------------------------------------------------------------------------------------------
BM_format_string&lt;char&gt;/1                         -0.1122         -0.1143  
          55            49            55            49
BM_format_string&lt;char&gt;/2                         -0.0999         -0.1020  
          28            25            28            25
BM_format_string&lt;char&gt;/4                         -0.1148         -0.1169  
          14            12            14            12
BM_format_string&lt;char&gt;/8                         -0.1186         -0.1207  
           7             6             7             6
BM_format_string&lt;char&gt;/16                        -0.1222         -0.1243  
           4             3             4             3
BM_format_string&lt;char&gt;/32                        -0.1417         -0.1438  
           2             2             2             2
BM_format_string&lt;char&gt;/64                        -0.1407         -0.1427  
           1             1             1             1
BM_format_string&lt;char&gt;/128                       -0.1559         -0.1579  
           1             1             1             1
BM_format_string&lt;char&gt;/256                       +0.0249         +0.0222  
           0             0             0             0
BM_format_string&lt;char&gt;/512                       -0.2473         -0.2491  
           0             0             0             0
BM_format_string&lt;char&gt;/1024                      -0.4661         -0.4674  
           0             0             0             0
BM_format_string&lt;char&gt;/2048                      -0.5096         -0.5111  
           0             0             0             0
BM_format_string&lt;char&gt;/4096                      -0.6278         -0.6287  
           0             0             0             0
BM_format_string&lt;char&gt;/8192                      -0.6674         -0.6683  
           0             0             0             0
BM_format_string&lt;char&gt;/16384                     -0.1005         -0.1027  
           0             0             0             0
BM_format_string&lt;char&gt;/32768                     -0.2127         -0.2147  
           0             0             0             0
BM_format_string&lt;char&gt;/65536                     -0.5796         -0.5781  
           0             0             0             0
BM_format_string&lt;char&gt;/131072                    -0.7844         -0.7844  
           0             0             0             0
BM_format_string&lt;char&gt;/262144                    -0.0073         -0.0086  
           1             1             1             1
BM_format_string&lt;char&gt;/524288                    +0.0017         +0.0005  
           1             1             1             1
BM_format_string&lt;char&gt;/1048576                   +0.0039         +0.0037  
           1             1             1             1
BM_format_string&lt;wchar_t&gt;/1                      -0.1304         -0.1307  
          56            49            56            49
BM_format_string&lt;wchar_t&gt;/2                      -0.1285         -0.1286  
          28            24            28            24
BM_format_string&lt;wchar_t&gt;/4                      -0.1288         -0.1288  
          14            12            14            12
BM_format_string&lt;wchar_t&gt;/8                      -0.1547         -0.1547  
           9             8             9             8
BM_format_string&lt;wchar_t&gt;/16                     -0.1681         -0.1681  
           5             4             5             4
BM_format_string&lt;wchar_t&gt;/32                     -0.1579         -0.1580  
           2             2             2             2
BM_format_string&lt;wchar_t&gt;/64                     -0.2443         -0.2444  
           1             1             1             1
BM_format_string&lt;wchar_t&gt;/128                    -0.4400         -0.4399  
           1             1             1             1
BM_format_string&lt;wchar_t&gt;/256                    -0.0535         -0.0535  
           1             1             1             1
BM_format_string&lt;wchar_t&gt;/512                    -0.0563         -0.0563  
           1             1             1             1
BM_format_string&lt;wchar_t&gt;/1024                   -0.1018         -0.1018  
           1             1             1             1
BM_format_string&lt;wchar_t&gt;/2048                   -0.0910         -0.0910  
           1             0             1             0
BM_format_string&lt;wchar_t&gt;/4096                   +0.4528         +0.4527  
           1             1             1             1
BM_format_string&lt;wchar_t&gt;/8192                   +0.3121         +0.3124  
           1             1             1             1
BM_format_string&lt;wchar_t&gt;/16384                  +0.2059         +0.2059  
           1             1             1             1
BM_format_string&lt;wchar_t&gt;/32768                  +0.1316         +0.1290  
           1             1             1             1
BM_format_string&lt;wchar_t&gt;/65536                  +0.1604         +0.1610  
           1             1             1             1
BM_format_string&lt;wchar_t&gt;/131072                 +0.1326         +0.1326  
           1             1             1             1
BM_format_string&lt;wchar_t&gt;/262144                 +0.1181         +0.1179  
           3             3             3             3
BM_format_string&lt;wchar_t&gt;/524288                 +0.5515         +0.5527  
           2             3             2             3
BM_format_string&lt;wchar_t&gt;/1048576                +0.1007         +0.1011  
           2             3             2             3
OVERALL_GEOMEAN                                  -0.1685         -0.1693        
     0             0             0             0

---
Full diff: https://github.com/llvm/llvm-project/pull/101817.diff


2 Files Affected:

- (modified) libcxx/include/__format/buffer.h (+237-18) 
- (modified) libcxx/include/__format/format_functions.h (+12-12) 


``````````diff
diff --git a/libcxx/include/__format/buffer.h b/libcxx/include/__format/buffer.h
index 8598f0a1c0395..1f26bfa923a6a 100644
--- a/libcxx/include/__format/buffer.h
+++ b/libcxx/include/__format/buffer.h
@@ -58,23 +58,156 @@ namespace __format {
 /// This helper is used together with the @ref back_insert_iterator to offer
 /// type-erasure for the formatting functions. This reduces the number to
 /// template instantiations.
+///
+/// The design of the class is being changed to improve performance and do some
+/// code cleanups.
+/// The original design (as shipped up to LLVM-19) uses the following design:
+/// - There is an external object that connects the buffer to the output.
+/// - The class constructor stores a function pointer to a grow function and a
+///   type-erased pointer to the object that does the grow.
+/// - When writing data to the buffer would exceed the external buffer's
+///   capacity it requests the external buffer to flush its contents.
+///
+/// The new design tries to solve some issues with the current design:
+/// - The buffer used is a fixed-size buffer, benchmarking shows that using a
+///   dynamic allocated buffer has performance benefits.
+/// - Implementing P3107R5 "Permit an efficient implementation of std::print"
+///   is not trivial with the current buffers. Using the code from this series
+///   makes it trivial.
+///
+/// This class is ABI-tagged, still the new design does not change the size of
+/// objects of this class.
+///
+/// The new design contains information regarding format_to_n changes, these
+/// will be implemented in follow-up patch.
+///
+/// The new design is the following.
+/// - There is an external object that connects the buffer to the output.
+/// - This buffer object:
+///   - inherits publicly from this class.
+///   - has a static or dynamic buffer.
+///   - has a static member function to make space in its buffer write
+///     operations. This can be done by increasing the size of the internal
+///     buffer or by writing the contents of the buffer to the output iterator.
+///
+///     This member function is a constructor argument, so its name is not
+///     fixed. The code uses the name __prepare_write.
+/// - The number of output code units can be limited by a __max_output_size
+///   object. This is used in format_to_n This object:
+///   - Contains the maximum number of code units to be written.
+///   - Contains the number of code units that are requested to be written.
+///     This number is returned to the user of format_to_n.
+///   - The write functions call objects __request_write member function.
+///     This function:
+///     - Updates the number of code units that are requested to be written.
+///     - Returns the number of code units that can be written without
+///       exceeding the maximum number of code units to be written.
+///
+/// Documentation for the buffer usage members:
+/// - __ptr_ the start of the buffer.
+/// - __capacity_ the number of code units that can be written.
+///   This means [__ptr_, __ptr_ + __capacity_) is a valid range to write to.
+/// - __size_ the number of code units written in the buffer. The next code
+///   unit will be written at __ptr_ + __size_. This __size_ may NOT contain
+///   the total number of code units written by the __output_buffer. Whether or
+///   not it does depends on the sub-class used. Typically the total number of
+///   code units written is not interesting. It is interesting for format_to_n
+///   which has its own way to track this number.
+///
+/// Documentation for the buffer changes function:
+/// The subclasses have a function with the following signature:
+///
+///   static void __prepare_write(
+///     __output_buffer<_CharT>& __buffer, size_t __code_units);
+///
+/// This function is called when a write function writes more code units than
+/// the buffer' available space. When an __max_output_size object is provided
+/// the number of code units is the number of code units returned from
+/// __max_output_size::__request_write function.
+///
+/// - The __buffer contains *this. Since the class containing this function
+///   inherits from __output_buffer it's save to cast it to the subclass being
+///   used.
+/// - The __code_units is the number of code units the caller will write + 1.
+///   - This value does not take the avaiable space of the buffer into account.
+///   - The push_back function is more efficient when writing before resizing,
+///     this means the buffer should always have room for one code unit. Hence
+///     the + 1 is the size.
+/// - When the function returns there is room for at least one code unit. There
+///   is no requirement there is room for __code_units code units:
+///   - The class has some "bulk" operations. For example, __copy which copies
+///     the contents of a basic_string_view to the output. If the sub-class has
+///     a fixed size buffer the size of the basic_string_view may be larger
+///     than the buffer. In that case it's impossible to honor the requested
+///     size.
+///   - The at least one code unit makes sure the entire output can be written.
+///     (Obviously making room one code unit at a time is slow and
+///     it's recommended to return a larger available space.)
+///   - When the buffer has room for at least one code unit the function may be
+///     a no-op.
+/// - When the function makes space for more code units it uses one for these
+///   functions to signal the change:
+///   - __buffer_flushed()
+///     - This function is typically used for a fixed sized buffer.
+///     - The current contents of [__ptr_, __ptr_ + __size_) have been
+///       processed.
+///     - __ptr_ remains unchanged.
+///     - __capacity_ remains unchanged.
+///     - __size_ will be set to 0.
+///   - __buffer_moved(_CharT* __ptr, size_t __capacity)
+///     - This function is typically used for a dynamic sized buffer. There the
+///       location of the buffer changes due to reallocations.
+///     - __ptr_ will be set to __ptr. (This value may be the old value of
+///       __ptr_).
+///     - __capacity_ will be set to __capacity. (This value may be the old
+///       value of       __capacity_).
+///     - __size_ remains unchanged,
+///     - The range [__ptr, __ptr + __size_) contains the original data of the
+///       range  [__ptr_, __ptr_ + __size_).
+///
+/// The push_back function expects a valid buffer and a capacity of at least 1.
+/// This means:
+/// - The class is constructed with a valid buffer,
+/// - __buffer_moved is called with a valid buffer is used before the first
+///   write operation,
+/// - no write function is ever called, or
+/// - the class is constructed with a __max_output_size object with __max_size 
0.
+///
+/// The latter option allows formatted_size to use the output buffer without
+/// ever writing anything to the buffer.
 template <__fmt_char_type _CharT>
 class _LIBCPP_TEMPLATE_VIS __output_buffer {
 public:
-  using value_type = _CharT;
+  using value_type           = _CharT;
+  using __prepare_write_type = void (*)(__output_buffer<_CharT>&, size_t);
 
-  template <class _Tp>
+  template <class _Tp> // Deprecated LLVM-19 function.
   _LIBCPP_HIDE_FROM_ABI explicit __output_buffer(_CharT* __ptr, size_t 
__capacity, _Tp* __obj)
       : __ptr_(__ptr),
         __capacity_(__capacity),
         __flush_([](_CharT* __p, size_t __n, void* __o) { 
static_cast<_Tp*>(__o)->__flush(__p, __n); }),
         __obj_(__obj) {}
 
+  // New LLVM-20 function.
+  [[nodiscard]]
+  _LIBCPP_HIDE_FROM_ABI explicit __output_buffer(_CharT* __ptr, size_t 
__capacity, __prepare_write_type __prepare_write)
+      : __ptr_(__ptr), __capacity_(__capacity), 
__prepare_write_(__prepare_write), __obj_(nullptr) {}
+
+  // Deprecated LLVM-19 function.
   _LIBCPP_HIDE_FROM_ABI void __reset(_CharT* __ptr, size_t __capacity) {
     __ptr_      = __ptr;
     __capacity_ = __capacity;
   }
 
+  // New LLVM-20 function.
+  _LIBCPP_HIDE_FROM_ABI void __buffer_flused() { __size_ = 0; }
+
+  // New LLVM-20 function.
+  _LIBCPP_HIDE_FROM_ABI void __buffer_moved(_CharT* __ptr, size_t __capacity) {
+    __ptr_      = __ptr;
+    __capacity_ = __capacity;
+  }
+
   _LIBCPP_HIDE_FROM_ABI auto __make_output_iterator() { return 
std::back_insert_iterator{*this}; }
 
   // Used in std::back_insert_iterator.
@@ -84,7 +217,7 @@ class _LIBCPP_TEMPLATE_VIS __output_buffer {
     // Profiling showed flushing after adding is more efficient than flushing
     // when entering the function.
     if (__size_ == __capacity_)
-      __flush();
+      __flush(0);
   }
 
   /// Copies the input __str to the buffer.
@@ -107,7 +240,7 @@ class _LIBCPP_TEMPLATE_VIS __output_buffer {
     size_t __n = __str.size();
 
     __flush_on_overflow(__n);
-    if (__n < __capacity_) { //  push_back requires the buffer to have room 
for at least one character (so use <).
+    if (__n < __capacity_) { // push_back requires the buffer to have room for 
at least one character (so use <).
       std::copy_n(__str.data(), __n, std::addressof(__ptr_[__size_]));
       __size_ += __n;
       return;
@@ -118,12 +251,12 @@ class _LIBCPP_TEMPLATE_VIS __output_buffer {
     _LIBCPP_ASSERT_INTERNAL(__size_ == 0, "the buffer should be flushed by 
__flush_on_overflow");
     const _InCharT* __first = __str.data();
     do {
-      size_t __chunk = std::min(__n, __capacity_);
+      size_t __chunk = std::min(__n, __capacity_ - __size_);
       std::copy_n(__first, __chunk, std::addressof(__ptr_[__size_]));
       __size_ = __chunk;
       __first += __chunk;
       __n -= __chunk;
-      __flush();
+      __flush(__n);
     } while (__n);
   }
 
@@ -148,12 +281,12 @@ class _LIBCPP_TEMPLATE_VIS __output_buffer {
     // Transform the data in "__capacity_" sized chunks.
     _LIBCPP_ASSERT_INTERNAL(__size_ == 0, "the buffer should be flushed by 
__flush_on_overflow");
     do {
-      size_t __chunk = std::min(__n, __capacity_);
+      size_t __chunk = std::min(__n, __capacity_ - __size_);
       std::transform(__first, __first + __chunk, 
std::addressof(__ptr_[__size_]), __operation);
       __size_ = __chunk;
       __first += __chunk;
       __n -= __chunk;
-      __flush();
+      __flush(__n);
     } while (__n);
   }
 
@@ -174,20 +307,36 @@ class _LIBCPP_TEMPLATE_VIS __output_buffer {
       std::fill_n(std::addressof(__ptr_[__size_]), __chunk, __value);
       __size_ = __chunk;
       __n -= __chunk;
-      __flush();
+      __flush(__n);
     } while (__n);
   }
 
-  _LIBCPP_HIDE_FROM_ABI void __flush() {
-    __flush_(__ptr_, __size_, __obj_);
-    __size_ = 0;
+  _LIBCPP_HIDE_FROM_ABI void __flush(size_t __size_hint) {
+    if (__obj_) {
+      // LLVM-19 code path
+      __flush_(__ptr_, __size_, __obj_);
+      __size_ = 0;
+    } else {
+      // LLVM-20 code path
+      __prepare_write_(*this, __size_hint + 1); // + 1 to always have space 
for the next time
+    }
   }
 
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI size_t __capacity() const { return 
__capacity_; }
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI size_t __size() const { return __size_; }
+
 private:
   _CharT* __ptr_;
   size_t __capacity_;
   size_t __size_{0};
-  void (*__flush_)(_CharT*, size_t, void*);
+  union {
+    // LLVM-19 member
+    void (*__flush_)(_CharT*, size_t, void*);
+    // LLVM-20 member
+    void (*__prepare_write_)(__output_buffer<_CharT>&, size_t);
+  };
+  static_assert(sizeof(__flush_) == sizeof(__prepare_write_), "The union is an 
ABI break.");
+  static_assert(alignof(decltype(__flush_)) == 
alignof(decltype(__prepare_write_)), "The union is an ABI break.");
   void* __obj_;
 
   /// Flushes the buffer when the output operation would overflow the buffer.
@@ -224,11 +373,14 @@ class _LIBCPP_TEMPLATE_VIS __output_buffer {
   /// the buffers. This would make the code more complex and \ref format_to_n 
is
   /// not the most common use case. Therefore the optimization isn't done.
   _LIBCPP_HIDE_FROM_ABI void __flush_on_overflow(size_t __n) {
-    if (__size_ + __n >= __capacity_)
-      __flush();
+    __n += __size_;
+    if (__n >= __capacity_)
+      __flush(__n - __capacity_ + 1);
   }
 };
 
+// ***** ***** ***** LLVM-19 classes ***** ***** *****
+
 /// A storage using an internal buffer.
 ///
 /// This storage is used when writing a single element to the output iterator
@@ -373,7 +525,7 @@ class _LIBCPP_TEMPLATE_VIS __format_buffer {
   _LIBCPP_HIDE_FROM_ABI void __flush(_CharT* __ptr, size_t __n) { 
__writer_.__flush(__ptr, __n); }
 
   _LIBCPP_HIDE_FROM_ABI _OutIt __out_it() && {
-    __output_.__flush();
+    __output_.__flush(0);
     return std::move(__writer_).__out_it();
   }
 
@@ -395,7 +547,7 @@ class _LIBCPP_TEMPLATE_VIS __formatted_size_buffer {
   _LIBCPP_HIDE_FROM_ABI void __flush(const _CharT*, size_t __n) { __size_ += 
__n; }
 
   _LIBCPP_HIDE_FROM_ABI size_t __result() && {
-    __output_.__flush();
+    __output_.__flush(0);
     return __size_;
   }
 
@@ -499,11 +651,78 @@ struct _LIBCPP_TEMPLATE_VIS __format_to_n_buffer final
   _LIBCPP_HIDE_FROM_ABI auto __make_output_iterator() { return 
this->__output_.__make_output_iterator(); }
 
   _LIBCPP_HIDE_FROM_ABI format_to_n_result<_OutIt> __result() && {
-    this->__output_.__flush();
+    this->__output_.__flush(0);
     return {std::move(this->__writer_).__out_it(), this->__size_};
   }
 };
 
+// ***** ***** ***** LLVM-20 classes ***** ***** *****
+
+// A dynamically growing buffer.
+template <__fmt_char_type _CharT>
+class _LIBCPP_TEMPLATE_VIS __allocating_buffer : public 
__output_buffer<_CharT> {
+public:
+  __allocating_buffer(const __allocating_buffer&)            = delete;
+  __allocating_buffer& operator=(const __allocating_buffer&) = delete;
+
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI __allocating_buffer()
+      : __output_buffer<_CharT>{__buffer_, __buffer_size_, __prepare_write} {}
+
+  _LIBCPP_HIDE_FROM_ABI ~__allocating_buffer() {
+    if (__ptr_ != __buffer_) {
+      ranges::destroy_n(__ptr_, this->__size());
+      allocator_traits<_Alloc>::deallocate(__alloc_, __ptr_, 
this->__capacity());
+    }
+  }
+
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI basic_string_view<_CharT> __view() { 
return {__ptr_, this->__size()}; }
+
+private:
+  // At the moment the allocator is hard-code. There might be reasons to have
+  // an allocator trait in the future. This ensures forward compatibility.
+  using _Alloc = allocator<_CharT>;
+  _LIBCPP_NO_UNIQUE_ADDRESS _Alloc __alloc_;
+
+  // Since allocating is expensive the class has a small internal buffer. When
+  // its capacity is exceeded a dynamic buffer will be allocated.
+  static constexpr size_t __buffer_size_ = 256;
+  _CharT __buffer_[__buffer_size_];
+  _CharT* __ptr_{__buffer_};
+
+  _LIBCPP_HIDE_FROM_ABI void __grow_buffer(size_t __capacity) {
+    if (__capacity < __buffer_size_)
+      return;
+
+    _LIBCPP_ASSERT_INTERNAL(__capacity > this->__capacity(), "the buffer must 
grow");
+    auto __result = std::__allocate_at_least(__alloc_, __capacity);
+    auto __guard  = std::__make_exception_guard([&] {
+      allocator_traits<_Alloc>::deallocate(__alloc_, __result.ptr, 
__result.count);
+    });
+    // This shouldn't throw, but just to be safe. Note that at -O1 this
+    // guard is optimized away so there is no runtime overhead.
+    new (__result.ptr) _CharT[__result.count];
+    std::copy_n(__ptr_, this->__size(), __result.ptr);
+    __guard.__complete();
+    if (__ptr_ != __buffer_) {
+      ranges::destroy_n(__ptr_, this->__capacity());
+      allocator_traits<_Alloc>::deallocate(__alloc_, __ptr_, 
this->__capacity());
+    }
+
+    __ptr_ = __result.ptr;
+    this->__buffer_moved(__ptr_, __result.count);
+  }
+
+  _LIBCPP_HIDE_FROM_ABI void __prepare_write(size_t __size_hint) {
+    __grow_buffer(std::max<size_t>(this->__capacity() + __size_hint, 
this->__capacity() * 1.6));
+  }
+
+  _LIBCPP_HIDE_FROM_ABI static void __prepare_write(__output_buffer<_CharT>& 
__buffer, size_t __size_hint) {
+    
static_cast<__allocating_buffer<_CharT>&>(__buffer).__prepare_write(__size_hint);
+  }
+};
+
+// ***** ***** ***** LLVM-19 and LLVM-20 class ***** ***** *****
+
 // A dynamically growing buffer intended to be used for retargeting a context.
 //
 // P2286 Formatting ranges adds range formatting support. It allows the user to
diff --git a/libcxx/include/__format/format_functions.h 
b/libcxx/include/__format/format_functions.h
index d14b49aff1495..a5c63bd4db70f 100644
--- a/libcxx/include/__format/format_functions.h
+++ b/libcxx/include/__format/format_functions.h
@@ -452,9 +452,9 @@ format_to(_OutIt __out_it, wformat_string<_Args...> __fmt, 
_Args&&... __args) {
 // fires too eagerly, see http://llvm.org/PR61563.
 template <class = void>
 [[nodiscard]] _LIBCPP_ALWAYS_INLINE inline _LIBCPP_HIDE_FROM_ABI string 
vformat(string_view __fmt, format_args __args) {
-  string __res;
-  std::vformat_to(std::back_inserter(__res), __fmt, __args);
-  return __res;
+  __format::__allocating_buffer<char> __buffer;
+  std::vformat_to(__buffer.__make_output_iterator(), __fmt, __args);
+  return string{__buffer.__view()};
 }
 
 #  ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
@@ -463,9 +463,9 @@ template <class = void>
 template <class = void>
 [[nodiscard]] _LIBCPP_ALWAYS_INLINE inline _LIBCPP_HIDE_FROM_ABI wstring
 vformat(wstring_view __fmt, wformat_args __args) {
-  wstring __res;
-  std::vformat_to(std::back_inserter(__res), __fmt, __args);
-  return __res;
+  __format::__allocating_buffer<wchar_t> __buffer;
+  std::vformat_to(__buffer.__make_output_iterator(), __fmt, __args);
+  return wstring{__buffer.__view()};
 }
 #  endif
 
@@ -585,9 +585,9 @@ format_to(_OutIt __out_it, locale __loc, 
wformat_string<_Args...> __fmt, _Args&&
 template <class = void>
 [[nodiscard]] _LIBCPP_ALWAYS_INLINE inline _LIBCPP_HIDE_FROM_ABI string
 vformat(locale __loc, string_view __fmt, format_args __args) {
-  string __res;
-  std::vformat_to(std::back_inserter(__res), std::move(__loc), __fmt, __args);
-  return __res;
+  __format::__allocating_buffer<char> __buffer;
+  std::vformat_to(__buffer.__make_output_iterator(), std::move(__loc), __fmt, 
__args);
+  return string{__buffer.__view()};
 }
 
 #    ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
@@ -596,9 +596,9 @@ vformat(locale __loc, string_view __fmt, format_args 
__args) {
 template <class = void>
 [[nodiscard]] _LIBCPP_ALWAYS_INLINE inline _LIBCPP_HIDE_FROM_ABI wstring
 vformat(locale __loc, wstring_view __fmt, wformat_args __args) {
-  wstring __res;
-  std::vformat_to(std::back_inserter(__res), std::move(__loc), __fmt, __args);
-  return __res;
+  __format::__allocating_buffer<wchar_t> __buffer;
+  std::vformat_to(__buffer.__make_output_iterator(), std::move(__loc), __fmt, 
__args);
+  return wstring{__buffer.__view()};
 }
 #    endif
 

``````````

</details>


https://github.com/llvm/llvm-project/pull/101817
_______________________________________________
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits

Reply via email to