WebWorker 计算缓慢的 regexp 匹配要慢得多(3x)-只有 firefox

首先,我自己创建了一个正则表达式,它将匹配项目中所有头文件列表中的所有唯一外部库路径。一周前。

我开始到处干预,看看它在异步和转变为 web worker 时会有什么反应。为了方便和可靠,我创建了这个通用文件,它可以在所有三种模式下运行:

/** 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;

我创建了一个测试文件,而不是粘贴在这里,我上传了非常可靠的网络托管: 演示-测试数据

令我感到非常惊讶的是,Web worker 和 RegExp 的浏览器执行之间存在如此显著的差异。我得到的结果是:

  • Mozilla Firefox
    • [WORKER]: Time elapsed:16.860s
    • [WORKER-SYNC]: Time elapsed:16.739s
    • [TIMEOUT]: Time elapsed:5.186s
    • [LOOP]: Time elapsed:5.028s

您还可以看到,对于我的特定正则表达式,同步循环和异步循环之间的区别是微不足道的。我尝试使用匹配列表而不是前瞻表达式,结果发生了很大变化。以下是对旧函数的更改:

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 ...
}

结果是:

  • Mozilla Firefox
    • [WORKER]: Time elapsed:0.062s
    • [WORKER-SYNC]: Time elapsed:0.023s
    • [TIMEOUT]: Time elapsed:12.250s(提醒自己: 它变得越来越怪异的每一分钟)
    • [LOOP]: Time elapsed:0.006s

有人能解释这种速度上的差异吗?

2087 次浏览

After a series of tests, I confirmed that this is a Mozilla Firefox issue (it affects all windows desktop versions I tried). With Google Chrome, Opera, or even Firefox mobile, the regexp matches take about the same, worker or not.

If you need this issue fixed, be sure to vote on bug report on bugzilla. I will try to add additional information if anything changes.