[javascript] WebWorker는 느린 regexp 일치를 상당히 느리게 (3x) 계산합니다.
먼저 프로젝트의 모든 헤더 파일 목록에서 모든 고유 한 외부 라이브러리 경로와 일치하는 정규식을 직접 만들었습니다. 일주일 전에 정규 표현식을 만드는 것에 대해 질문 했습니다.
비동기식 일 때와 웹 워커로 변했을 때 어떻게 동작하는지 알아보기 위해 개입하기 시작했습니다. 편의성과 안정성을 위해 세 가지 모드 모두에서 실행되는이 범용 파일을 만들었습니다.
/** 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
누구든지 속도의 차이를 설명 할 수 있습니까?
답변
일련의 테스트 후, 이것이 Mozilla Firefox 문제임을 확인했습니다 (내가 시도한 모든 Windows 데스크톱 버전에 영향을 미침). Google Chrome, Opera 또는 Firefox 모바일에서 정규 표현식 일치는 작업자 여부와 상관없이 거의 동일합니다.
이 문제를 수정해야하는 경우 bugzilla의 버그 보고서에 투표하세요 . 변경 사항이 있으면 추가 정보를 추가하려고합니다.