Branch: refs/heads/main
  Home:   https://github.com/WebKit/WebKit
  Commit: 56dcc0037aa258bc1c52ab3742874be18768ef6e
      
https://github.com/WebKit/WebKit/commit/56dcc0037aa258bc1c52ab3742874be18768ef6e
  Author: Chris Dumez <[email protected]>
  Date:   2026-01-08 (Thu, 08 Jan 2026)

  Changed paths:
    M Source/WTF/wtf/text/ASCIIFastPath.h
    M Source/WTF/wtf/text/StringCommon.h
    M Source/WTF/wtf/text/StringImpl.cpp

  Log Message:
  -----------
  Optimize StringImpl::create8BitIfPossible()
https://bugs.webkit.org/show_bug.cgi?id=304792

Reviewed by Darin Adler.

Optimize StringImpl::create8BitIfPossible(). Avoid allocating new string
unnecessarily in the "slow" path. Rely on highly optimized `copyElements()`
to copy characters in the fast path. I also rely on `charactersAreAllLatin1()`
to determine if we can use the fast path and found out it was a lot slower
than `std::ranges::all_of()` with larger strings containing non-Latin1.

As a result, I also optimized `charactersAreAllLatin1()` as follows:
- Included a SIMD implementation for ARM64 NEON.
- Early return when finding a non-Latin1 character to avoid scanning to
  whole string unnecessarily.

With these changes, StringImpl::create8BitIfPossible() is now consisently
faster than it used to be for all kinds of input strings:

================
=== All ASCII (8-bit compatible) ===
Benchmark                     Version   Size      Avg (ns)    Min (ns)    Max 
(ns)    MB/s        Result
--------------------------------------------------------------------------------------------------------------
AllASCII                      Old       1         21.39       0.00        
12208.00    93.52       8-bit
AllASCII                      New       1         15.70       0.00        
17916.00    127.37      8-bit
    → Speedup: 1.36x (faster by 26.58%)

AllASCII                      Old       8         16.56       0.00        
13417.00    966.37      8-bit
AllASCII                      New       8         15.43       0.00        
10292.00    1036.92     8-bit
    → Speedup: 1.07x (faster by 6.80%)

AllASCII                      Old       16        17.62       0.00        
11000.00    1815.86     8-bit
AllASCII                      New       16        15.39       0.00        
14583.00    2078.72     8-bit
    → Speedup: 1.14x (faster by 12.65%)

AllASCII                      Old       32        19.55       0.00        
11834.00    3273.16     8-bit
AllASCII                      New       32        15.83       0.00        
11833.00    4043.32     8-bit
    → Speedup: 1.24x (faster by 19.05%)

AllASCII                      Old       64        27.82       0.00        
10291.00    4600.73     8-bit
AllASCII                      New       64        16.90       0.00        
20292.00    7571.86     8-bit
    → Speedup: 1.65x (faster by 39.24%)

AllASCII                      Old       128       56.19       0.00        
14375.00    4555.87     8-bit
AllASCII                      New       128       18.30       0.00        
12416.00    13990.88    8-bit
    → Speedup: 3.07x (faster by 67.44%)

AllASCII                      Old       256       111.16      41.00       
26791.00    4606.15     8-bit
AllASCII                      New       256       21.84       0.00        
12833.00    23442.15    8-bit
    → Speedup: 5.09x (faster by 80.35%)

AllASCII                      Old       512       181.74      83.00       
23250.00    5634.35     8-bit
AllASCII                      New       512       33.45       0.00        
24000.00    30610.58    8-bit
    → Speedup: 5.43x (faster by 81.59%)

AllASCII                      Old       1024      311.10      208.00      
30583.00    6583.02     8-bit
AllASCII                      New       1024      67.20       0.00        
18750.00    30476.86    8-bit
    → Speedup: 4.63x (faster by 78.40%)

AllASCII                      Old       4096      1083.80     916.00      
46291.00    7558.62     8-bit
AllASCII                      New       4096      244.86      166.00      
18959.00    33455.68    8-bit
    → Speedup: 4.43x (faster by 77.41%)

AllASCII                      Old       16384     4171.20     3625.00     
43958.00    7855.77     8-bit
AllASCII                      New       16384     871.47      666.00      
29083.00    37600.87    8-bit
    → Speedup: 4.79x (faster by 79.11%)

AllASCII                      Old       65536     16447.48    14541.00    
55250.00    7969.12     8-bit
AllASCII                      New       65536     3175.16     2750.00     
27125.00    41280.49    8-bit
    → Speedup: 5.18x (faster by 80.70%)

=== All 16-bit Required ===
Benchmark                     Version   Size      Avg (ns)    Min (ns)    Max 
(ns)    MB/s        Result
--------------------------------------------------------------------------------------------------------------
All16Bit                      Old       1         21.05       0.00        
14333.00    95.02       16-bit
All16Bit                      New       1         14.23       0.00        
10541.00    140.55      16-bit
    → Speedup: 1.48x (faster by 32.40%)

All16Bit                      Old       8         20.79       0.00        
17125.00    769.56      16-bit
All16Bit                      New       8         15.76       0.00        
19083.00    1015.50     16-bit
    → Speedup: 1.32x (faster by 24.22%)

All16Bit                      Old       16        21.53       0.00        
15042.00    1486.21     16-bit
All16Bit                      New       16        15.31       0.00        
18250.00    2089.74     16-bit
    → Speedup: 1.41x (faster by 28.88%)

All16Bit                      Old       32        21.63       0.00        
49667.00    2958.18     16-bit
All16Bit                      New       32        15.66       0.00        
10625.00    4087.71     16-bit
    → Speedup: 1.38x (faster by 27.63%)

All16Bit                      Old       64        22.93       0.00        
15375.00    5583.00     16-bit
All16Bit                      New       64        15.99       0.00        
25791.00    8003.13     16-bit
    → Speedup: 1.43x (faster by 30.24%)

All16Bit                      Old       128       24.44       0.00        
14959.00    10474.61    16-bit
All16Bit                      New       128       16.76       0.00        
19792.00    15278.07    16-bit
    → Speedup: 1.46x (faster by 31.44%)

All16Bit                      Old       256       29.16       0.00        
18750.00    17559.42    16-bit
All16Bit                      New       256       20.34       0.00        
18500.00    25171.53    16-bit
    → Speedup: 1.43x (faster by 30.24%)

All16Bit                      Old       512       37.72       0.00        
19667.00    27143.93    16-bit
All16Bit                      New       512       23.07       0.00        
8375.00     44382.30    16-bit
    → Speedup: 1.64x (faster by 38.84%)

All16Bit                      Old       1024      52.62       0.00        
21584.00    38918.68    16-bit
All16Bit                      New       1024      33.23       0.00        
10583.00    61636.57    16-bit
    → Speedup: 1.58x (faster by 36.86%)

All16Bit                      Old       4096      118.67      41.00       
17541.00    69032.42    16-bit
All16Bit                      New       4096      98.49       0.00        
25083.00    83177.57    16-bit
    → Speedup: 1.20x (faster by 17.01%)

All16Bit                      Old       16384     455.45      291.00      
26208.00    71947.19    16-bit
All16Bit                      New       16384     297.08      208.00      
30208.00    110299.11   16-bit
    → Speedup: 1.53x (faster by 34.77%)

All16Bit                      Old       65536     1335.24     1083.00     
23208.00    98163.39    16-bit
All16Bit                      New       65536     1239.36     1000.00     
24333.00    105757.95   16-bit
    → Speedup: 1.08x (faster by 7.18%)

=== 16-bit Character at End ===
Benchmark                     Version   Size      Avg (ns)    Min (ns)    Max 
(ns)    MB/s        Result
--------------------------------------------------------------------------------------------------------------
16BitAtEnd                    Old       8         22.05       0.00        
11875.00    725.63      16-bit
16BitAtEnd                    New       8         15.39       0.00        
14791.00    1039.83     16-bit
    → Speedup: 1.43x (faster by 30.22%)

16BitAtEnd                    Old       64        39.59       0.00        
12250.00    3233.51     16-bit
16BitAtEnd                    New       64        17.01       0.00        
17375.00    7525.66     16-bit
    → Speedup: 2.33x (faster by 57.03%)

16BitAtEnd                    Old       512       220.28      125.00      
28750.00    4648.65     16-bit
16BitAtEnd                    New       512       36.31       0.00        
16625.00    28199.77    16-bit
    → Speedup: 6.07x (faster by 83.52%)

16BitAtEnd                    Old       4096      1196.95     1000.00     
30958.00    6844.05     16-bit
16BitAtEnd                    New       4096      253.95      166.00      
27458.00    32258.79    16-bit
    → Speedup: 4.71x (faster by 78.78%)

16BitAtEnd                    Old       65536     17901.83    15708.00    
58875.00    7321.71     16-bit
16BitAtEnd                    New       65536     3276.21     2833.00     
38125.00    40007.20    16-bit
    → Speedup: 5.46x (faster by 81.70%)

=== 16-bit Character at Start ===
Benchmark                     Version   Size      Avg (ns)    Min (ns)    Max 
(ns)    MB/s        Result
--------------------------------------------------------------------------------------------------------------
16BitAtStart                  Old       8         20.80       0.00        
21166.00    769.36      16-bit
16BitAtStart                  New       8         15.57       0.00        
13125.00    1027.74     16-bit
    → Speedup: 1.34x (faster by 25.14%)

16BitAtStart                  Old       64        22.06       0.00        
17083.00    5802.22     16-bit
16BitAtStart                  New       64        15.92       0.00        
17917.00    8039.36     16-bit
    → Speedup: 1.39x (faster by 27.83%)

16BitAtStart                  Old       512       38.28       0.00        
18916.00    26751.01    16-bit
16BitAtStart                  New       512       22.94       0.00        
17667.00    44646.57    16-bit
    → Speedup: 1.67x (faster by 40.08%)

16BitAtStart                  Old       4096      116.60      41.00       
18958.00    70257.22    16-bit
16BitAtStart                  New       4096      96.39       0.00        
53875.00    84990.64    16-bit
    → Speedup: 1.21x (faster by 17.34%)

16BitAtStart                  Old       65536     1340.98     1083.00     
28333.00    97743.33    16-bit
16BitAtStart                  New       65536     1247.90     1000.00     
28666.00    105033.84   16-bit
    → Speedup: 1.07x (faster by 6.94%)

=== Mixed (90% 8-bit) ===
Benchmark                     Version   Size      Avg (ns)    Min (ns)    Max 
(ns)    MB/s        Result
--------------------------------------------------------------------------------------------------------------
Mixed90                       Old       64        24.67       0.00        
15667.00    5187.81     16-bit
Mixed90                       New       64        15.99       0.00        
8709.00     8006.46     16-bit
    → Speedup: 1.54x (faster by 35.20%)

Mixed90                       Old       512       41.39       0.00        
10834.00    24741.84    16-bit
Mixed90                       New       512       23.41       0.00        
16750.00    43737.15    16-bit
    → Speedup: 1.77x (faster by 43.43%)

Mixed90                       Old       4096      129.96      41.00       
21625.00    63032.45    16-bit
Mixed90                       New       4096      97.66       41.00       
21834.00    83878.94    16-bit
    → Speedup: 1.33x (faster by 24.85%)

Mixed90                       Old       65536     1353.72     1083.00     
22250.00    96823.82    16-bit
Mixed90                       New       65536     1238.73     1041.00     
21125.00    105811.28   16-bit
    → Speedup: 1.09x (faster by 8.49%)
================

* Source/WTF/wtf/text/ASCIIFastPath.h:
(WTF::isLatin1):
(WTF::charactersAreAllLatin1):
* Source/WTF/wtf/text/StringCommon.h:
(WTF::isLatin1): Deleted.
* Source/WTF/wtf/text/StringImpl.cpp:
(WTF::StringImpl::create8BitIfPossible):

Canonical link: https://commits.webkit.org/305259@main



To unsubscribe from these emails, change your notification settings at 
https://github.com/WebKit/WebKit/settings/notifications

Reply via email to