Another JavaScript Microbenchmark

Since the core of Adblock’s functionality is matching regular expressions against URLs, I figured it’d be useful to do some microbenchmarks to see (A) how fast the various regexp functions are on their own, and (B) how they compare to the built-in string comparison functions.

Remember that Gecko’s JS timers are only precise to twentieth-of-seconds or so.


Compiling an empty regexp, then matching it against a string 100,000 times:

var re1 = /(?:)/i;
var start = Date.now();
var s= 'http://www.xulplanet.com/tutorials/xultu/broadob.html';
for(var j = 100000; j; --j) { re1.test(s); }
(Date.now() - start);

~560 ms. No appreciable difference for making a case-sensitive match, as seems logical — we’re not actually matching anything. Same results for /.*?/ , with or without case-insensitivity.


Comparing a literal empty string to a literal non-empty string (41 chars) 100,000 times takes roughly 90 ms. Comparing variables is ~115.


Comparing stringA to stringB.substr(0,5) [that is, the first five characters of a 60-char stringB] 100,000 times takes ~1500 ms.
Doing /^http\:/i.test(s), however, takes only 600 ms.


var re1 = /^http\:/i; var start = Date.now();
var s2 = 'http:'; var s= 'http://www.xulplanet.com/tutorials/xultu/broadob.html';
for(var j = 100000; j; --j) { s2 == s.substr(0,5); }
(Date.now() - start);

Increasing the size of s to 531 characters had no visible effect upon runtime.


Traditional haystack.indexOf(needle) searching takes 900-1000 ms, which is slower than a regular expression. If anyone ever tells you that they’re using .indexOf() instead of a regexp because it’s faster… well, they’re probably wrong, unless they’re working with very very large haystacks…


var start = Date.now();
var s2 = 'http:'; var s= 'http://www.xulplanet.com/tutorials/xultu/broadob.html';
for(var j = 100000; j; --j) { s.indexOf(s2) == 0; }
(Date.now() - start);

More complex regular expressions (with 3 backreferences) on a short test string:
.test() still takes ~600 ms.
.exec() takes ~4300 ms.
.match() takes ~6500 ms
.match() on the same regexp without backrefrences takes ~1800 ms
.search() takes ~1700 ms
.search() passed a string (constructing a regexp every time) takes ~5000 ms


var re1 = /a (short( )st(ri)ng)\2compa\3son/;
var start = Date.now(); var s2 = 'a short string comparison';
for(var j = 100000; j; --j) {  re1.test(s2); }
(Date.now() - start);

With a 540 character string,
.test() is 2500 ms,
.exec() is too
.match() w/o backrefs is ~3600 ms

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s