WebWorker 计算慢速正则表达式匹配速度明显慢 (3x) - 仅限 firefox
WebWorker calculates slow regexp matches significantly slower (3x) - firefox only
首先,我自己创建了一个正则表达式,它将匹配项目中所有头文件列表中所有唯一的外部库路径。 一周前。
我开始四处看看它在异步和变成网络工作者时的行为。为了方便和可靠,我创建了这个在所有三种模式下运行的通用文件:
/** 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;
我创建了一个测试文件,而不是将其粘贴到此处,而是将其上传到非常可靠的虚拟主机上:Demo - Test data.
令我感到非常惊讶的是,web worker 和浏览器执行 RegExp 之间存在如此显着的差异。我得到的结果:
- 火狐浏览器
<strong>[工人]:</strong>时间elapsed:16.860s
<strong>[WORKER-SYNC]:</strong>时间elapsed:16.739s
<strong>[TIMEOUT]:</strong>时间elapsed:5.186s
<strong>[循环]:</strong>时间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 ...
}
结果:
- 火狐浏览器
<strong>[工人]:</strong>时间elapsed:0.062s
<strong>[WORKER-SYNC]:</strong>时间elapsed:0.023s
<strong>[TIMEOUT]:</strong>时间elapsed:12.250s
(自我提醒:每分钟都在变怪)
<strong>[循环]:</strong>时间elapsed:0.006s
谁能解释速度上的这种差异?
经过一系列测试,我确认这是一个 Mozilla Firefox 问题(它影响我尝试过的所有 windows 桌面版本)。使用 Google Chrome、Opera,甚至 Firefox 移动版,正则表达式匹配的时间大致相同,无论是否为 worker。
如果您需要解决此问题,请务必在 bug report on bugzilla 上投票。如果有任何变化,我会尝试添加其他信息。
首先,我自己创建了一个正则表达式,它将匹配项目中所有头文件列表中所有唯一的外部库路径。
我开始四处看看它在异步和变成网络工作者时的行为。为了方便和可靠,我创建了这个在所有三种模式下运行的通用文件:
/** 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;
我创建了一个测试文件,而不是将其粘贴到此处,而是将其上传到非常可靠的虚拟主机上:Demo - Test data.
令我感到非常惊讶的是,web worker 和浏览器执行 RegExp 之间存在如此显着的差异。我得到的结果:
- 火狐浏览器
<strong>[工人]:</strong>时间elapsed:16.860s
<strong>[WORKER-SYNC]:</strong>时间elapsed:16.739s
<strong>[TIMEOUT]:</strong>时间elapsed:5.186s
<strong>[循环]:</strong>时间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 ...
}
结果:
- 火狐浏览器
<strong>[工人]:</strong>时间elapsed:0.062s
<strong>[WORKER-SYNC]:</strong>时间elapsed:0.023s
<strong>[TIMEOUT]:</strong>时间elapsed:12.250s
(自我提醒:每分钟都在变怪)<strong>[循环]:</strong>时间elapsed:0.006s
谁能解释速度上的这种差异?
经过一系列测试,我确认这是一个 Mozilla Firefox 问题(它影响我尝试过的所有 windows 桌面版本)。使用 Google Chrome、Opera,甚至 Firefox 移动版,正则表达式匹配的时间大致相同,无论是否为 worker。
如果您需要解决此问题,请务必在 bug report on bugzilla 上投票。如果有任何变化,我会尝试添加其他信息。