WebWorker计算缓慢的正则expression式匹配显着慢(3倍) – 只有Firefox

首先,我创build了一个正则expression式,它将匹配项目中所有头文件列表中的所有唯一外部库path。 我在一个星期前提出了一个有关制定这个正则expression式的问题 。

我开始介入,看看它在asynchronous和变成networking工作者时会有什么样的performance。 为了方便和可靠,我创build了这个以所有三种模式运行的通用文件:

/** Will call result() callback with every match it founds. Asynchronous unless called * with interval = -1. * Javadoc style comment for Arnold Rimmer and other Java programmers: * * @param regex regular expression to match in string * @param string guess what * @param result callback function that accepts one parameter, string match * @param done callback on finish, has no parameters * @param interval delay (not actual interval) between finding matches. If -1, * function will be blocking * @property working false if loop isn't running, otherwise contains timeout ID * for use with clearTimeout * @property done copy of done parameter * @throws heavy boulders **/ function processRegex(regex, string, result, done, interval) { var m; //Please tell me interpreter optimizes this interval = typeof interval!='number'?1:interval; //And this processRegex.done = done; while ((m = regex.exec(string))) { Array.prototype.splice.call(m,0,1); var path = m.join(""); //It's good to keep in mind that result() slows down the process result(path); if (interval>=0) { processRegex.working = setTimeout(processRegex, interval, regex, string, result, done, interval); // Comment these out for maximum speed processRegex.progress = regex.lastIndex/string.length; console.log("Progress: "+Math.round(processRegex.progress*100)+"%"); return; } } processRegex.working = false; processRegex.done = null; if (typeof done=="function") done(); } processRegex.working = false; 

我创build了一个testing文件,而不是粘贴在这里,我上传了非常可靠的networking托pipe: 演示 – testing数据 。

我感到非常惊讶的是,networking工作者和RegExp的浏览器执行之间存在着如此显着的差异。 我得到的结果:

  • 火狐浏览器
    • [WORKER]: Time elapsed:16.860s
    • [WORKER-SYNC]: Time elapsed:16.739s
    • [TIMEOUT]: Time elapsed:5.186s
    • [LOOP]: Time elapsed:5.028s

你也可以看到,用我特定的正则expression式,同步和asynchronous循环之间的区别是微不足道的。 我试图使用一个匹配列表,而不是一个先行expression式,结果改变了很多。 以下是对旧function的更改:

 function processRegexUnique(regex, string, result, done, interval) { var matchList = arguments[5]||[]; ... same as before ... while ((m = regex.exec(string))) { ... same as before ... if (matchList.indexOf(path)==-1) { result(path); matchList.push(path); } if (interval>=0) { processRegex.working = setTimeout(processRegex, interval, regex, string, result, done, interval, matchList); ... same as before ... } } ... same as before ... } 

结果是:

  • 火狐浏览器
    • [WORKER]: Time elapsed:0.062s
    • [WORKER-SYNC]: Time elapsed:0.023s
    • [TIMEOUT]: Time elapsed:12.250s (注意自己:每分钟都会变得越来越[TIMEOUT]: Time elapsed:12.250s
    • [LOOP]: Time elapsed:0.006s

任何人都可以解释这种速度差异?

经过一系列testing,我确认这是一个Mozilla Firefox问题(它会影响我尝试的所有Windows桌面版本)。 使用谷歌浏览器,Opera,甚至是Firefox手机,正则expression式匹配大致相同,工作者与否。

如果您需要解决此问题,请务必对bugzilla的bug报告进行投票。 如果有任何更改,我会尝试添加其他信息。