RegExp vs indexOf: ABP miss (v6)

Revision 6 of this benchmark created by AlexV on


Description

Which is faster for single wildcard-based ABP filters?

Setup

function FilterRegex(s, tokenBeg) {
      this.s = s;
      this.tokenBeg = tokenBeg;
      this.re = new RegExp('^' + s.replace(/([.+?^=!:${}()|\[\]\/\\])/g, '\\$1').replace(/\*/g, '.*'));
    }
    
    FilterRegex.prototype.match = function(s, tokenBeg) {
      return this.re.test(s.slice(tokenBeg - this.tokenBeg));
    };
    
    function FilterMultiRegex(sarray) {
      var res = '^(?:';
      var i = sarray.length;
      while(i--) {
        res += sarray[i].replace(/([.+?^=!:${}()|\[\]\/\\])/g, '\\$1').replace(/\*/g, '.*')
        if (i) {
            res += '|';
        }
      }
      this.re = new RegExp(res + ')');
    }
    
    FilterMultiRegex.prototype.match = function(s, tokenBeg) {
      return this.re.test(s.slice(tokenBeg));
    };
    
    function FilterIndexOf(s, tokenBeg) {
      this.s = s;
      this.tokenBeg = tokenBeg;
      var wcOffset = s.indexOf('*');
      this.lSegment = s.slice(0, wcOffset);
      this.rSegment = s.slice(wcOffset + 1);
    }
    
    FilterIndexOf.prototype.match = function(s, tokenBeg) {
      tokenBeg -= this.tokenBeg;
      return s.indexOf(this.lSegment, tokenBeg) === tokenBeg &&
        s.indexOf(this.rSegment, tokenBeg + this.lSegment.length) > 0;
    };
    
    function FilterSubstr(s, tokenBeg) {
        this.s = s;
        this.next = undefined;
        this.tokenBeg = tokenBeg;
        var wcOffset = s.indexOf('*');
        this.lSegment = s.slice(0, wcOffset);
        this.rSegment = s.slice(wcOffset + 1);
    }
    
    FilterSubstr.prototype.match = function(s, tokenBeg) {
      tokenBeg -= this.tokenBeg;
      return s.substr(tokenBeg, this.lSegment.length) === this.lSegment &&
             s.indexOf(this.rSegment, tokenBeg + this.lSegment.length) > 0;
    };
    
    // "http://m.bestofmedia.com/s/52896/commun/css/new/default.static.header.less.tha.min.css"
    var frem1 = new FilterRegex("static.hd-trailers.net/js/javascript_*.js|", 0);
    var fiom1 = new FilterIndexOf("static.hd-trailers.net/js/javascript_*.js|", 0);
    var fssm1 = new FilterSubstr("static.hd-trailers.net/js/javascript_*.js|", 0);
    
    // "http://cdn.echoenabled.com/clientapps/v2/backplane.js"
    var frem2 = new FilterRegex("cdn.epom.com*/940_250.gif", 0);
    var fiom2 = new FilterIndexOf("cdn.epom.com*/940_250.gif", 0);
    var fssm2 = new FilterSubstr("cdn.epom.com*/940_250.gif", 0);
    
    // "https://apis.google.com/js/plusone.js"
    var frem3 = new FilterRegex("google.com/images/*_promo_", 0);
    var fiom3 = new FilterIndexOf("google.com/images/*_promo_", 0);
    var fssm3 = new FilterSubstr("google.com/images/*_promo_", 0);
    
    // "http://www.wired.com/css/global.css?v=20121120a"
    var frem4 = new FilterRegex("wired.com/images/xrail/*/samsung_layar", 0);
    var fiom4 = new FilterIndexOf("wired.com/images/xrail/*/samsung_layar", 0);
    var fssm4 = new FilterSubstr("wired.com/images/xrail/*/samsung_layar", 0);
    // "http://s0.wp.com/_static/??-eJx9js0OwiAQhF9Iuq1tiB6Mz0JhA7T8BbZtfHsJJxO1t5nNtzMDR2IyBsJA4DeW3KZtKODsigUWpCTkyprrZCkX+I37xOvZJ0FNmvr0zZNBX0N3m4BQGpm3IA279sMIhV4OO2/DWUnG2UVdpYZKfdh/TWYC7eIs3FnqYZVGKi1Sx6gyCtW2P/1jGO9Tz6cb58sbzNNsjw=="
    var frem5 = new FilterRegex("wp.com/wp-content/themes/vip/tctechcrunch/images/tc_*_skin.jpg", 0);
    var fiom5 = new FilterIndexOf("wp.com/wp-content/themes/vip/tctechcrunch/images/tc_*_skin.jpg", 0);
    var fssm5 = new FilterSubstr("wp.com/wp-content/themes/vip/tctechcrunch/images/tc_*_skin.jpg", 0);
    
    var fremulti = new FilterMultiRegex([
    "static.hd-trailers.net/js/javascript_*.js|",
    "cdn.epom.com*/940_250.gif",
    "google.com/images/*_promo_",
    "wired.com/images/xrail/*/samsung_layar",
    "wp.com/wp-content/themes/vip/tctechcrunch/images/tc_*_skin.jpg"
    ]);

Test runner

Ready to run.

Testing in
TestOps/sec
RegExp miss
if (frem1.match("http://m.bestofmedia.com/s/52896/commun/css/new/default.static.header.less.tha.min.css", 56) ||
    frem2.match("http://cdn.echoenabled.com/clientapps/v2/backplane.js", 7) || 
    frem3.match("https://apis.google.com/js/plusone.js", 13) ||
    frem4.match("http://www.wired.com/css/global.css?v=20121120a", 11) ||
    frem5.match("http://s0.wp.com/_static/??-eJx9js0OwiAQhF9Iuq1tiB6Mz0JhA7T8BbZtfHsJJxO1t5nNtzMDR2IyBsJA4DeW3KZtKODsigUWpCTkyprrZCkX+I37xOvZJ0FNmvr0zZNBX0N3m4BQGpm3IA279sMIhV4OO2/DWUnG2UVdpYZKfdh/TWYC7eIs3FnqYZVGKi1Sx6gyCtW2P/1jGO9Tz6cb58sbzNNsjw==", 10) ) {
  throw 'gah!';
}
ready
indexOf miss
if (fiom1.match("http://m.bestofmedia.com/s/52896/commun/css/new/default.static.header.less.tha.min.css", 56) ||
    fiom2.match("http://cdn.echoenabled.com/clientapps/v2/backplane.js", 7) || 
    fiom3.match("https://apis.google.com/js/plusone.js", 13) ||
    fiom4.match("http://www.wired.com/css/global.css?v=20121120a", 11) ||
    fiom5.match("http://s0.wp.com/_static/??-eJx9js0OwiAQhF9Iuq1tiB6Mz0JhA7T8BbZtfHsJJxO1t5nNtzMDR2IyBsJA4DeW3KZtKODsigUWpCTkyprrZCkX+I37xOvZJ0FNmvr0zZNBX0N3m4BQGpm3IA279sMIhV4OO2/DWUnG2UVdpYZKfdh/TWYC7eIs3FnqYZVGKi1Sx6gyCtW2P/1jGO9Tz6cb58sbzNNsjw==", 10) ) {
  throw 'gah!';
}
 
ready
substr miss
if (fssm1.match("http://m.bestofmedia.com/s/52896/commun/css/new/default.static.header.less.tha.min.css", 56) ||
    fssm2.match("http://cdn.echoenabled.com/clientapps/v2/backplane.js", 7) || 
    fssm3.match("https://apis.google.com/js/plusone.js", 13) ||
    fssm4.match("http://www.wired.com/css/global.css?v=20121120a", 11) ||
    fssm5.match("http://s0.wp.com/_static/??-eJx9js0OwiAQhF9Iuq1tiB6Mz0JhA7T8BbZtfHsJJxO1t5nNtzMDR2IyBsJA4DeW3KZtKODsigUWpCTkyprrZCkX+I37xOvZJ0FNmvr0zZNBX0N3m4BQGpm3IA279sMIhV4OO2/DWUnG2UVdpYZKfdh/TWYC7eIs3FnqYZVGKi1Sx6gyCtW2P/1jGO9Tz6cb58sbzNNsjw==", 10) ) {
  throw 'gah!';
}
 
ready
Multi RegEx (1)
if (fremulti.match("http://m.bestofmedia.com/s/52896/commun/css/new/default.static.header.less.tha.min.css", 56)) {
  throw 'gah!';
}
ready
Multi RegEx (2)
if (fremulti.match("http://cdn.echoenabled.com/clientapps/v2/backplane.js", 7)) {
  throw 'gah!';
}
ready
Multi RegEx (3)
if (fremulti.match("https://apis.google.com/js/plusone.js", 13)) {
  throw 'gah!';
}
ready
Multi RegEx (4)
if (fremulti.match("http://www.wired.com/css/global.css?v=20121120a", 11)) {
  throw 'gah!';
}
ready
Multi RegEx (5)
if (fremulti.match("http://s0.wp.com/_static/??-eJx9js0OwiAQhF9Iuq1tiB6Mz0JhA7T8BbZtfHsJJxO1t5nNtzMDR2IyBsJA4DeW3KZtKODsigUWpCTkyprrZCkX+I37xOvZJ0FNmvr0zZNBX0N3m4BQGpm3IA279sMIhV4OO2/DWUnG2UVdpYZKfdh/TWYC7eIs3FnqYZVGKi1Sx6gyCtW2P/1jGO9Tz6cb58sbzNNsjw==", 10)) {
  throw 'gah!';
}
ready

Revisions

You can edit these tests or add more tests to this page by appending /edit to the URL.