regexp vs indexOf

JavaScript performance comparison

Test case created by John-David Dalton

Info

Checking the performance cost of using a regexp instead of String#indexOf.

Preparation code

<div id="foo" class="a foo bar"></div>
<script>
Benchmark.prototype.setup = function() {
    var r;
    var element = document.getElementById('foo');
    var reContains = /(?:^| )foo(?: |$)/;
   
    function dynamicRegExp(node) {
      return RegExp('(?:^| )foo(?: |$)').test(node.className);
    }
   
    function inlineRegExp(node) {
      return /(?:^| )foo(?: |$)/.test(node.className);
    }
   
    function storedRegExp(node) {
      return reContains.test(node.className);
    }
   
    function stringIndexOf(node) {
      return (' ' + node.className + ' ').indexOf(' foo ') > -1;
    }
   
   
};
</script>

Preparation code output

Test runner

Warning! For accurate results, please disable Firebug before running the tests. (Why?)

Java applet disabled.

Testing in unknown unknown
Test Ops/sec
dynamic regexp
r = dynamicRegExp(element);
pending…
inline regexp
r = inlineRegExp(element);
pending…
stored regexp
r = storedRegExp(element);
pending…
string indexOf
r = stringIndexOf(element);
pending…

Compare results of other browsers

Revisions

You can edit these tests or add even more tests to this page by appending /edit to the URL. Here’s a list of current revisions for this page:

5 comments

Robert K commented :

Why is this messing around with a DomElement, when what you're trying to test is RegExp .vs. non-RegExp methods of searching strings?

Using "node.className" as the target is introducing browser specific code-paths for resolving DOM classnames, which have nothing to do with what you're trying to test here, no???

Bill Goates commented :

It's the ' ' + node.className + ' ' that makes the indexOf test slow.

John-David Dalton (revision owner) commented :

The point of this test is to show that you should avoid making blanket assumptions about performance and that you shouldn't fear the RegExp :)

@Robert K

Why is this messing around with a DomElement, when what you're trying to test is RegExp vs. non-RegExp methods of searching strings?

I wanted to use a common use case of checking if an element has a specific class name because I've seen libs toss-n-turn over using one or the other.

Using "node.className" as the target is introducing browser specific code-paths for resolving DOM classnames, which have nothing to do with what you're trying to test here, no???

Possibly, but it seems not to be a big factor in the overall outcome: regexp-indexof-perf/11.

Another interesting revision that uses memoizes: regexp-indexof-perf/10

@Bill Goates

It keeps the tests functionally equivalent. If I removed the ' ' + node.className + ' ' then it would fail to detect a possible className value of 'foo a bar'.

Wayne Bloss commented :

Your indexOf test is still broken because of that concatenation though. You're testing the speed of concat + indexOf not just indexOf.

Why don't you pass in a value that is padded already for this test?

John-David Dalton (revision owner) commented :

@Wayne Bloss

Your indexOf test is still broken because of that concatenation though. You're testing the speed of concat + indexOf not just indexOf.

The test isn't broken in the scope of its use case. You are totally missing the point which is RegExp's are no longer a guaranteed fail when it comes to performance and that in many situations, including this jsPerf test, can out perform the indexOf equivalent.

Why don't you pass in a value that is padded already for this test?

Because that's not common use. The point was to check your assumptions about performance not that RegExp's are always faster than indexOf.

Add a comment