WebWorker는 느린 regexp 일치를 상당히 느리게 (3x) 계산합니다.


85

먼저 프로젝트의 모든 헤더 파일 목록에서 모든 고유 한 외부 라이브러리 경로와 일치하는 정규식을 직접 만들었습니다. 일주일 전에 정규 표현식을 만드는 것에 대해 질문 했습니다.

비동기식 일 때와 웹 워커로 변했을 때 어떻게 동작하는지 알아보기 위해 개입하기 시작했습니다. 편의성과 안정성을 위해 세 가지 모드 모두에서 실행되는이 범용 파일을 만들었습니다.

/** 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 에 업로드했습니다 .

제가 매우 놀라운 사실은 웹 워커와 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을 추가 할 수 있습니까? 파이어 폭스 버그를 아직 제출하지 않았다면 시간을 할애 해 주시면 감사하겠습니다.
sideshowbarker

@sideshowbarker 파이어 폭스 버그를보고 할 곳을 봤는데 실패했습니다. 그래서 나는 파이어 폭스 입력 ( " 파이어 폭스가 나를 슬프게했다. ")에 " 버그를보고 할 수있는 곳을 찾을 수 없다 "라는 불만을 채워 포기했다. 버그를 신고 할 위치를 알고있는 경우 (실제 신고 절차이며 사용자 피드백을위한 일부 싱크가 아님) 알려주세요. 안정적으로 재현하고 파이어 폭스 전용으로 식별 할 수있는 문제를 발견 한 것은 이번이 처음이 아닙니다.
Tomáš Zato-Monica 복원

1
네, 그들이 할 수있는 한 명확하지 않다는 데 동의했습니다. 어쨌든,이 특정 버그에 대해서는 bugzilla.mozilla.org/… 를 사용하십시오 . DOM: Workers그러면 적절한 bugzilla Core제품 의 적절한 bugzilla 구성 요소에 대해 문제가 발생합니다 .
sideshowbarker

1
다른 사람들이 Firefox 브라우저 엔진 버그를보고 할 때 겪었던 동일한 좌절감을 피하기 위해 stackoverflow.com/questions/33059442/를 만들었습니다. 여기에 해당 정보를 기록하는 것이 유용하다고 생각한다면 StackOverflow, 그것을 업 보팅하는 것을 고려하십시오 (그렇지 않으면 다른 슬픔에 찬 모든 것의 반대 투표자가 악 대차에 뛰어 들면 삭제 될 위험이 있습니다).
sideshowbarker

1
의도적으로 패턴이 느립니다. 훨씬 더 효율적인 방법은 미리보기를 건너 뛰고 대신 참조 배열을 사용하는 것입니다. 그러나이 질문은 실제로 최적의 코드를 작성하는 것이 아닙니다.
Tomáš Zato-Monica 복원

답변:


2

일련의 테스트 후, 이것이 Mozilla Firefox 문제임을 확인했습니다 (내가 시도한 모든 Windows 데스크톱 버전에 영향을 미침). Google Chrome, Opera 또는 Firefox 모바일에서 정규 표현식 일치는 작업자 여부와 상관없이 거의 동일합니다.

이 문제를 수정해야하는 경우 bugzilla의 버그 보고서에 투표하세요 . 변경 사항이 있으면 추가 정보를 추가하려고합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.