WebWorker计算慢速正则表达式匹配的速度明显慢(3x)-仅适用于Firefox


85

首先,我只是为自己创建了一个正则表达式,该表达式将匹配项目中所有头文件列表中的所有唯一外部库路径。一周前问过一个关于制作该正则表达式的问题

我开始四处看看,以了解异步和变成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托管:Demo - Test data

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

  • 火狐浏览器
    • [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 ...
}

结果:

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

谁能解释这种速度差异?


6
如果您为此提交了Firefox错误,可以将错误URL添加到您的问题中吗?而且,如果您尚未为此提交Firefox错误,希望您可以考虑花些时间这样做。
sideshowbarker

@sideshowbarker我在google上报告了firefox错误的地方,但失败了。因此,我在firefox输入中填写了“找不到错误报告位置”的投诉(“ Firefox使我难过。 ”),然后放弃了。如果您知道在哪里报告错误(这是实际的报告过程,而没有一些反馈给用户),请告诉我。这不是我第一次发现可以可靠地重现并标识为仅Firefox的问题。
托马什Zato -恢复莫妮卡

1
是的,他们并没有说清楚。无论如何,对于这个特定的错误,请使用bugzilla.mozilla.org/…这将使其与DOM: Workers适当的bugzillaCore产品中的适当的bugzilla组件相对应。
sideshowbarker

1
为了尝试帮助其他人避免遇到试图报告Firefox浏览器引擎错误的麻烦,我创建了stackoverflow.com/questions/33059442/…如果您认为在此处记录该信息很有用,请在StackOverflow,请考虑对其进行升级(否则,如果其他膝上举手投足的低级跳水者跳上潮流,则可能有被删除的风险)。
sideshowbarker

1
该模式故意变慢。更有效的方法是跳过前瞻,而使用引用数组。但是这个问题实际上与编写最佳代码无关。
托马什Zato -恢复莫妮卡

Answers:


2

经过一系列测试,我确认这是Mozilla Firefox问题(它影响了我尝试过的所有Windows桌面版本)。使用Google Chrome,Opera或什至是Firefox移动版,regexp匹配大约需要相同的工作线程,而无论工作线程与否。

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.