DEV Community

Suni
Suni

Posted on

Is startsWith Faster Than RegExp?

Today when writing conditional statements, I used String startsWith because I believed it would be the fastest way. Let me prove it!

Test

Device Information:

  • AMD Ryzen 5 5600X 6-Core Processor 3.70 GHz
  • 16.0 GB
  • node v18.12.1
const loopTimes = 10 ** 2

console.log('loop times:', loopTimes)
for (let j = 0; j < 10; j++) {
    {
        console.time('startsWith')

        for (let i = 0; i < loopTimes; i++) {
            'Performance-Comparison-Regular-Expression-vs-StartsWith'.startsWith('Performance-Compa')
        }

        console.timeEnd('startsWith')
    }

    {
        console.time('reg')

        for (let i = 0; i < loopTimes; i++) {
            ;/^Performance-Compa/.test('Performance-Comparison-Regular-Expression-vs-StartsWith')
        }

        console.timeEnd('reg')
    }
}
Enter fullscreen mode Exit fullscreen mode

Loop 10 ** 2 times

output:

$ node startsWith.js
loop times: 100
startsWith: 0.062ms
reg: 0.074ms
startsWith: 0.006ms
reg: 0.01ms
startsWith: 0.005ms
reg: 0.012ms
startsWith: 0.005ms
reg: 0.008ms
startsWith: 0.005ms
reg: 0.016ms
startsWith: 0.004ms
reg: 0.008ms
startsWith: 0.004ms
reg: 0.009ms
startsWith: 0.004ms
reg: 0.009ms
startsWith: 0.004ms
reg: 0.006ms
startsWith: 0.004ms
reg: 0.006ms
Enter fullscreen mode Exit fullscreen mode

Loop 10 ** 3 times

$ node startsWith.js
loop times: 1000
startsWith: 0.086ms
reg: 0.148ms
startsWith: 0.033ms
reg: 0.08ms
startsWith: 0.113ms
reg: 0.077ms
startsWith: 0.048ms
reg: 0.063ms
startsWith: 0.032ms
reg: 0.072ms
startsWith: 0.027ms
reg: 0.065ms
startsWith: 0.03ms
reg: 0.065ms
startsWith: 0.026ms
reg: 0.065ms
startsWith: 0.03ms
reg: 0.062ms
startsWith: 0.036ms
reg: 0.459ms
Enter fullscreen mode Exit fullscreen mode

Loop 10 ** 4 times

$ node startsWith.js
loop times: 10000
startsWith: 0.393ms
reg: 1.562ms
startsWith: 0.241ms
reg: 5.237ms
startsWith: 0.343ms
reg: 0.564ms
startsWith: 0.342ms
reg: 0.153ms
startsWith: 0.342ms
reg: 0.262ms
startsWith: 0.347ms
reg: 0.223ms
startsWith: 0.352ms
reg: 0.152ms
startsWith: 0.341ms
reg: 0.229ms
startsWith: 0.341ms
reg: 0.191ms
startsWith: 0.341ms
reg: 0.227ms
Enter fullscreen mode Exit fullscreen mode

Loop 10 ** 5 times

$ node startsWith.js
loop times: 100000
startsWith: 5.24ms
reg: 4.092ms
startsWith: 6.891ms
reg: 1.875ms
startsWith: 3.795ms
reg: 1.794ms
startsWith: 3.414ms
reg: 1.943ms
startsWith: 3.408ms
reg: 2.265ms
startsWith: 3.472ms
reg: 1.938ms
startsWith: 4.231ms
reg: 1.762ms
startsWith: 3.602ms
reg: 1.791ms
startsWith: 3.639ms
reg: 2.002ms
startsWith: 3.435ms
reg: 1.768ms
Enter fullscreen mode Exit fullscreen mode

Loop 10 ** 6 times

$ node startsWith.js
loop times: 1000000
startsWith: 36.477ms
reg: 20.72ms
startsWith: 39.39ms
reg: 17.669ms
startsWith: 34.748ms
reg: 17.519ms
startsWith: 35.174ms
reg: 17.366ms
startsWith: 35.09ms
reg: 17.527ms
startsWith: 34.822ms
reg: 17.597ms
startsWith: 34.615ms
reg: 17.87ms
startsWith: 35.453ms
reg: 17.855ms
startsWith: 35.786ms
reg: 17.613ms
startsWith: 34.706ms
reg: 17.6ms
Enter fullscreen mode Exit fullscreen mode

Loop 10 ** 7 times

$ node startsWith.js
loop times: 10000000
startsWith: 355.577ms
reg: 180.706ms
startsWith: 354.726ms
reg: 180.558ms
startsWith: 347.955ms
reg: 175.675ms
startsWith: 348.327ms
reg: 174.522ms
startsWith: 346.228ms
reg: 175.619ms
startsWith: 347.943ms
reg: 175.331ms
startsWith: 346.146ms
reg: 177.439ms
startsWith: 349.308ms
reg: 175.06ms
startsWith: 347.434ms
reg: 175.234ms
startsWith: 348.574ms
reg: 175.179ms
Enter fullscreen mode Exit fullscreen mode

Research

Things don't seem to have developed as expected. When the loop is increased to 10*4 times, the situation starts to reverse, and the consumption time of reg becomes shorter instead. By the time it reaches 10*7, there is a significant difference.

Shorter String

Change the code as follows:

'Suni123'.startsWith('Suni')
;/^Suni/.test('Suni123')
Enter fullscreen mode Exit fullscreen mode

10 ** 7 loops, output

$ node startsWith.js
loop times: 10000000
startsWith: 94.856ms
reg: 164.667ms
startsWith: 92.53ms
reg: 159.685ms
startsWith: 86.074ms
reg: 158.927ms
startsWith: 84.894ms
reg: 159.14ms
startsWith: 91.335ms
reg: 166.805ms
startsWith: 85.942ms
reg: 159.383ms
startsWith: 84.433ms
reg: 159.253ms
startsWith: 85.166ms
reg: 161.083ms
startsWith: 85.391ms
reg: 158.424ms
startsWith: 85.856ms
reg: 161.31ms
Enter fullscreen mode Exit fullscreen mode

At this point, startsWith is obviously faster.

Longer String

'Performance Comparison: Regular Expression vs. StartsWith; Performance Comparison: Regular Expression vs. StartsWith'.startsWith(
    'Performance Comparison: Regular Expression '
)
;/^Performance Comparison: Regular Expression /.test(
    'Performance Comparison: Regular Expression vs. StartsWith; Performance Comparison: Regular Expression vs. StartsWith'
)
Enter fullscreen mode Exit fullscreen mode

output

$ node startsWith.js
loop times: 10000000
startsWith: 892.246ms
reg: 206.517ms
startsWith: 901.182ms
reg: 203.149ms
startsWith: 902.196ms
reg: 202.142ms
startsWith: 897.693ms
reg: 203.393ms
startsWith: 890.596ms
reg: 223.431ms
startsWith: 894.55ms
reg: 204.961ms
startsWith: 896.698ms
reg: 203.099ms
startsWith: 901.242ms
reg: 202.968ms
startsWith: 902.59ms
reg: 202.787ms
startsWith: 909.052ms
reg: 214.305ms
Enter fullscreen mode Exit fullscreen mode

Long String, Short Condition

'Performance Comparison: Regular Expression vs. StartsWith; Performance Comparison: Regular Expression vs. StartsWith'.startsWith(
    'Performance'
)
;/^Performance/.test(
    'Performance Comparison: Regular Expression vs. StartsWith; Performance Comparison: Regular Expression vs. StartsWith'
)
Enter fullscreen mode Exit fullscreen mode
$ node startsWith.js
loop times: 10000000
startsWith: 228.98ms
reg: 173.04ms
startsWith: 234.776ms
reg: 167.778ms
startsWith: 228.642ms
reg: 168.327ms
startsWith: 228.746ms
reg: 174.96ms
startsWith: 228.663ms
reg: 168.228ms
startsWith: 229.287ms
reg: 167.576ms
startsWith: 227.067ms
reg: 168.668ms
startsWith: 228.117ms
reg: 168.955ms
startsWith: 227.062ms
reg: 169.838ms
startsWith: 228.28ms
reg: 168.242ms
Enter fullscreen mode Exit fullscreen mode

Long String, Long Condition

'Performance Comparison: Regular Expression vs. StartsWith; Performance Comparison: Regular Expression vs. StartsWith'.startsWith(
    'Performance Comparison: Regular Expression vs. StartsWith; Performance'
)
;/^Performance Comparison: Regular Expression vs. StartsWith; Performance/.test(
    'Performance Comparison: Regular Expression vs. StartsWith; Performance Comparison: Regular Expression vs. StartsWith'
)
Enter fullscreen mode Exit fullscreen mode
$ node startsWith.js
loop times: 10000000
startsWith: 1.439s
reg: 237.275ms
startsWith: 1.432s
reg: 242.409ms
startsWith: 1.437s
reg: 238.463ms
startsWith: 1.425s
reg: 232.626ms
startsWith: 1.423s
reg: 234.199ms
startsWith: 1.426s
reg: 234.651ms
startsWith: 1.440s
reg: 235.122ms
startsWith: 1.429s
reg: 234.676ms
startsWith: 1.444s
reg: 234.071ms
startsWith: 1.439s
reg: 235.936ms
Enter fullscreen mode Exit fullscreen mode

Reduce the Number of Loops

'Performance Comparison: Regular Expression vs. StartsWith; Performance Comparison: Regular Expression vs. StartsWith'.startsWith(
    'Performance Comparison: Regular Expression vs. StartsWith; Performance'
)
;/^Performance Comparison: Regular Expression vs. StartsWith; Performance/.test(
    'Performance Comparison: Regular Expression vs. StartsWith; Performance Comparison: Regular Expression vs. StartsWith'
)
Enter fullscreen mode Exit fullscreen mode

output

$ node startsWith.js
loop times: 1000
startsWith: 0.114ms
reg: 0.159ms
startsWith: 0.061ms
reg: 0.08ms
startsWith: 0.138ms
reg: 0.064ms
startsWith: 0.056ms
reg: 0.059ms
startsWith: 0.059ms
reg: 0.071ms
startsWith: 0.059ms
reg: 0.064ms
startsWith: 0.058ms
reg: 0.062ms
startsWith: 0.056ms
reg: 0.069ms
startsWith: 0.058ms
reg: 0.062ms
startsWith: 0.143ms
reg: 0.431ms
Enter fullscreen mode Exit fullscreen mode

10**4

$ node startsWith.js
loop times: 10000
startsWith: 0.735ms
reg: 1.016ms
startsWith: 0.674ms
reg: 3.743ms
startsWith: 1.498ms
reg: 0.575ms
startsWith: 1.404ms
reg: 0.211ms
startsWith: 1.408ms
reg: 0.313ms
startsWith: 1.425ms
reg: 0.28ms
startsWith: 1.727ms
reg: 0.337ms
startsWith: 1.724ms
reg: 0.303ms
startsWith: 1.404ms
reg: 0.21ms
startsWith: 1.408ms
reg: 0.282ms
Enter fullscreen mode Exit fullscreen mode

Conclusion

When dealing with short string, it is better to use startsWith. For longer string, it is better to use regular expression. When handling a long string with a short condition, startsWith is still a good choice.

In daily development, when the number of operations is less than 10^3, it is better to use startsWith. This also improves readability. However, when the number of operations exceeds this magnitude and the condition string is long, using regular expression will have better performance.

How will the browser behave?

chrome v114.0.5735.199

Chrome Console

Essentially the same as Node, it could lead to the same conclusions.

Other

During this test, I discovered that console.time can be used for timing, which is more convenient than using Date.now because it doesn't require recording the difference. It's a new discovery, haha ^o^.

console.clear can manually clear logs, console.assert can assert in the browser, console.trace can directly view the call stack, and console.count can be used to print the number of updates in a React FC. These are all quite useful.

Top comments (0)