Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript Firefox的正则表达式性能很差_Javascript_Regex_Performance_Firefox - Fatal编程技术网

Javascript Firefox的正则表达式性能很差

Javascript Firefox的正则表达式性能很差,javascript,regex,performance,firefox,Javascript,Regex,Performance,Firefox,我使用JavaScript解析器生成器为用户创建的一些脚本创建解析器。最近,我注意到Firefox上的解析过程比我的页面支持的任何其他浏览器(IE10,最新的Chrome&Opera)都要慢很多 在深入研究了生成的解析器的源代码之后,我将问题缩小到了一行代码,该行代码执行一些正则表达式来标记要解析的代码。当然,这一行经常被执行 我创建了一个带有一些随机字符串(约1300个字符长)和一个非常通用的正则表达式的小测试用例。此测试用例测量执行regex 10000次()所需的平均时间: $(文档).r

我使用JavaScript解析器生成器为用户创建的一些脚本创建解析器。最近,我注意到Firefox上的解析过程比我的页面支持的任何其他浏览器(IE10,最新的Chrome&Opera)都要慢很多

在深入研究了生成的解析器的源代码之后,我将问题缩小到了一行代码,该行代码执行一些正则表达式来标记要解析的代码。当然,这一行经常被执行

我创建了一个带有一些随机字符串(约1300个字符长)和一个非常通用的正则表达式的小测试用例。此测试用例测量执行regex 10000次()所需的平均时间:

$(文档).ready(函数(){
“AsDFAsAsFaFaFaFaFaFaFaFaFaFaFaFaFaFaFaFaFaFaFaFaFaFaFaFaFaFaFaFaFaFaFaFaFaFaFaFaFaFaFaFaFaFaFaFaFaFaFaFaFaFaFaFaFaFaFaFaFaFaFaFaFaFaFaFaFaFaFaFaFaFaFaFaFaFaFaFaFaFaFaFaFaFaFaFaFaFaFaFaFaFaFaFaFaFaFaFaFaAsAsAsAsAsAsAsFaFaFaFaFaFaFaFaFaFaFaFaFaFaFaFaFaFaFaFaAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsFaFaFaFaFaFaFaFaFaFaFaFaFaFaFaFaFaFaFaFaFaFaFaFaFaFaFaAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsFaFaFaFaFaFaFaFaFaFaFaFaFaFaFaFaFaFaFaFaFaFaFaAsAsAsAsAsAsAsAsAsAsAsAs询问dfjAsAsDFAsAsAsAsAsDFAsAsAsDFAsAsAsDFAsAsDFAsAsDFAsAsDFAsAsDFAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsDFAsAsAsDFAsAsAsDFAsAsAsDFAsAsDFAsAsDFAsAsDFAsAsDFAsAsDFAsAsDFAsAsDFAsAsDFAsDFAsAsDFAsDFAsAsDFAsAsAsDFAsAsAsDF作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为DFASDFAAsAsDFAsAsAsDFAsAsDFAsAsAsDFAsAsAsDFAsAsAsDFAsAsAsDFAsAsAsAsAsAsDFAsAsAsAsAsAsAsAsAsAsAsAsDFAsAsDFAsAsAsDFAsAsAsAsDFAsAsDFAsAsDFAsAsDFAsAsAsDFAsAsDFAsAsAsDFAsAsAsDFAsAsAsAsAsAsAsAsAsAsAs作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为作为DFASDFAsDFAsAsDFAsAsDFAsAsDFAsAsDFAsAsDFAsAsAsDFAsAsAsDFAsAsAsDFAsAsAsDFAsAsAsDFAsAsAsDFAsAsDFAsAsDFAsAsDFAsAsDFAsAsDFAsAsDFAsAsAsDFAsAsDFAsAsAsDFAsAsAsAsAsDFAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAs德德德德政政政政政政政政政政政政政政政政政政政政政政政政政政政政政政政政政政政政政政政政政政政政政政政政政政政政政政政政政政政政政政政政政政政政政政政政政政政政政政政政政政政政政政政政政政政政政政政政政政政政政政政政政政政政政政政政政政政政政政政政政政政政政政政政政政政政政政政政政政政政政政DF asdfasdfasödlfkja asldfkj asdölkfj aslödkjf aösldkfj',
regex=newregexp('^([0-9])+'),
持续时间=[],
resHtml='持续时间:',
totalDuration=0,
比赛,开始;
//执行“定时测试”10次,以获得一些平均持续时间
对于(变量i=0;i<10;i++){
//执行regex 10000次,看看需要多长时间
start=window.performance.now();
对于(var j=0;j<10000;j++){
regex.exec(str);
}
durations.push(window.performance.now()-start);
}
//创建输出字符串并更新DIV
对于(变量i=0;i
以下是在我的机器上的测试结果:

Firefox 24:10000个正则表达式执行的平均时间介于370到450毫秒之间
Chrome 30、Opera 17、IE 10:平均时间介于0.3和0.6 ms之间

如果要测试的字符串变大,这个差异会变得更大。6000个字符长的字符串将Firefox中的平均时间增加到~1.5秒(!),而其他浏览器仍然需要~0.5毫秒(!)()

为什么Firefox和所有其他浏览器之间的性能有如此大的差异,我可以改进它吗


请注意,我无法调整已执行的正则表达式,因为它们大部分是由解析器生成器生成的,我不想手动更改生成的解析器代码。

正是
RegExp
捕获分组让您:

/^[0-9]+/
和/或
/^(?[0-9])+/
和/或
/^([0-9]+)/
/^[0-9])+/
快几个数量级。它们应该是可行的替代方案

我希望捕获群组的速度会稍微慢一点,但速度如此之慢让我感到惊讶。然而,慢速版本有可能创建大量的捕获,而其他版本则没有,因此这似乎是一个重要的区别


您可能需要。

这要慢得多,因为regexp JIT Firefox和Safari use(Yarr)当前无法编译具有量化捕获的regexp(在上面的示例中,捕获参数后的
+
)。有关跟踪此错误的信息,请参阅。因此,regexp在Yarr regexp解释器中执行,这当然比运行JITted代码慢得多。
$(document).ready(function() {
    var str = 'asdfasdfa asdfasdf asdf asdf asdfasödlfkja asldfkj asdölkfj aslödkjf aösldkfj ölkasjd flöaksjdf löask dfjkasdfasdfa asdfasdf asdf asdf asdfasödlfkja asldfkj asdölkfj aslödkjf aösldkfj ölkasjd flöaksjdf löask dfjkasdfasdfa asdfasdf asdf asdf asdfasödlfkja asldfkj asdölkfj aslödkjf aösldkfj ölkasjd flöaksjdf löask dfjkasdfasdfa asdfasdf asdf asdf asdfasödlfkja asldfkj asdölkfj aslödkjf aösldkfj ölkasjd flöaksjdf löask dfjkasdfasdfa asdfasdf asdf asdf asdfasödlfkja asldfkj asdölkfj aslödkjf aösldkfj ölkasjd flöaksjdf löask dfjkasdfasdfa asdfasdf asdf asdf asdfasödlfkja asldfkj asdölkfj aslödkjf aösldkfj ölkasjd flöaksjdf löask dfjkasdfasdfa asdfasdf asdf asdf asdfasödlfkja asldfkj asdölkfj aslödkjf aösldkfj ölkasjd flöaksjdf löask dfjkasdfasdfa asdfasdf asdf asdf asdfasödlfkja asldfkj asdölkfj aslödkjf aösldkfj ölkasjd flöaksjdf löask dfjkasdfasdfa asdfasdf asdf asdf asdfasödlfkja asldfkj asdölkfj aslödkjf aösldkfj ölkasjd flöaksjdf löask dfjkasdfasdfa asdfasdf asdf asdf asdfasödlfkja asldfkj asdölkfj aslödkjf aösldkfj ölkasjd flöaksjdf löask dfjkasdfasdfa asdfasdf asdf asdf asdfasödlfkja asldfkj asdölkfj aslödkjf aösldkfj ölkasjd flöaksjdf löask dfjkasdfasdfa asdfasdf asdf asdf asdfasödlfkja asldfkj asdölkfj aslödkjf aösldkfj ölkasjd flöaksjdf löask dfjkasdfasdfa asdfasdf asdf asdf asdfasödlfkja asldfkj asdölkfj aslödkjf aösldkfj',
        regex = new RegExp('^([0-9])+'),
        durations = [],
        resHtml = 'Durations:',
        totalDuration = 0,
        matches, start;

    // Perform "timing test" 10 times to get some average duration
    for (var i = 0; i < 10; i++) {
        // Execute regex 10000 times and see how long it takes
        start = window.performance.now();
        for (var j = 0; j < 10000; j++) {
            regex.exec(str);
        }
        durations.push(window.performance.now() - start);
    }

    // Create output string and update DIV
    for (var i = 0; i < durations.length; i++) {
        totalDuration += durations[i];
        resHtml += '<br>' + i + ': ' + (parseInt(durations[i] * 100, 10) / 100) + ' ms';
    }
    resHtml += '<br>==========';
    resHtml += '<br>Avg: ' + (parseInt((totalDuration / durations.length) * 100, 10) / 100) + ' ms';

    $('#result').html(resHtml);
});