RegExp.exec vs RegExp.test + substr vs lastIndex (500,000, no match)

JavaScript performance comparison

Revision 2 of this test case created by Rob W

Info

Stack Overflow: Can a JavaScript RegExp match at an exact string offset without searching?.

Test case to compare the RegExp.test method vs RegExp.exec on large strings, by either using string.substr(index, 10) or regexp.lastIndex = index.

This test case creates a random string, consisting of approx. 2 * index characters. The regexp pattern matches a string with a length of 10. The substr method doesn't require the slow global flag, whereas the lastIndex method doesn't require a substr string operation.

The code at tests 1-3 can always be applied, while the code at test 4 can only be used for a specific case: When the RegExp returns a match with a fixed length

Other index values: 10,000, no match Edit the JSPerf with publish check OFF if you want to check other values.

Preparation code

<div id="message"></div><script>
//Define a random string consisting of ~ [two times index] alphanumeric chars
var index = 500000;
var string = createRandomString(2*index); //Warning: It may take a while before large (10mb+) strings are generated
//Create semi-unique RegExp + global flag for `.exec`
var regexp = new RegExp(string.substr(index,9)+'#', "g");
var regexpSubstr = new RegExp("^"+string.substr(index,9)+'#', "");

var message = "Preparation: Created a random string with length "+string.length + ", Using patterns " + regexp + " and " + regexpSubstr;
if(typeof console != "undefined" && typeof console.log == "function") console.log(message);
document.getElementById("message").innerHTML = message;


/* @name createRandomString
 * @author Rob W
 * @description Create a random string consisting of alphanumeric characters
 * @param Number num_patterns Specify the number of random patterns
 * @param Number repeat Specify the number of returned random patterns
 * @returns String (missing repeat param): String with a length of approx num_patterns
 * @returns String String with a length of approx number_patterns * patterns */

function createRandomString(num_patterns, repeat){
    //Using bitwise `>>0` to floor, for improved performance. As a result, the maximum returned string has a size of approx 2.1 Gb
    if(!repeat){
        repeat = Math.ceil(num_patterns/8);
        num_patterns = Math.ceil(num_patterns/8);
    } else {
        repeat = Math.abs(repeat >> 0);
        num_patterns = Math.min(Math.abs(num_patterns >> 0), repeat);
    }
    var patt = [], s = [], d =Math.pow(36,8)-1, i=0;
    for(; i<num_patterns; i++){
        patt.push(Math.floor(Math.random()*d).toString(36));
    }
    for(i=0; i<repeat; i++)
        s.push(patt[Math.random()*num_patterns>>0]);
    return s.join("");
}
</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
.exec + .substr
if ( regexpSubstr.exec(string.substr(index,10)) ) ; // `null` to `false`, `String` to `true` conversion
pending…
.exec + .lastIndex
regexp.lastIndex = index;
var found =  regexp.exec(string);
if (found && found.length + index == regexp.lastIndex ) ; //Matched string length + start index == lastIndex ?
pending…
.test + .substr
if ( regexpSubstr.test(string.substr(index,10)) ) ; // `null` to false, `String` to true conversion
pending…
.test + .lastIndex
// NOTE: This method is only effective when the RegExp pattern matches a fixed number of characters
regexp.lastIndex = index;
if ( regexp.test(string) && regexp.lastIndex == index + 10 ) ; // lastIndex == index + 10 ?
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:

0 comments

Add a comment