WebWorker tính toán các trận đấu regexp chậm chậm hơn đáng kể (3 lần) - chỉ dành cho firefox


85

Đầu tiên, tôi vừa tạo cho mình một biểu thức chính quy sẽ khớp với tất cả các đường dẫn thư viện bên ngoài duy nhất trong danh sách tất cả các tệp tiêu đề trong một dự án. Tôi đã hỏi một câu hỏi liên quan đến việc tạo regexp đó một tuần trước.

Tôi bắt đầu can thiệp xung quanh để xem nó sẽ hoạt động như thế nào khi không đồng bộ và khi được chuyển thành nhân viên web. Để thuận tiện và đáng tin cậy, tôi đã tạo tệp chung này chạy ở cả ba chế độ:

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

Tôi đã tạo một tệp thử nghiệm, thay vì dán nó ở đây, tôi đã tải nó lên lưu trữ web rất đáng tin cậy: Demo - Dữ liệu thử nghiệm .

Điều tôi thấy rất ngạc nhiên là có một sự khác biệt đáng kể giữa web worker và trình duyệt thực thi RegExp. Kết quả tôi nhận được:

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

Bạn cũng có thể thấy rằng với biểu thức chính quy cụ thể của tôi, sự khác biệt giữa vòng lặp đồng bộ và không đồng bộ là không đáng kể. Tôi đã cố gắng sử dụng danh sách đối sánh thay vì biểu thức nhìn trước và kết quả đã thay đổi rất nhiều. Dưới đây là những thay đổi đối với chức năng cũ:

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

Và kết quả:

  • Mozilla Firefox
    • [WORKER]: Time elapsed:0.062s
    • [WORKER-SYNC]: Time elapsed:0.023s
    • [TIMEOUT]: Time elapsed:12.250s (lưu ý với bản thân: nó trở nên kỳ lạ hơn mỗi phút)
    • [LOOP]: Time elapsed:0.006s

Bất cứ ai có thể giải thích một sự khác biệt về tốc độ?


6
Nếu bạn đã gửi một lỗi Firefox cho vấn đề này, bạn có thể thêm URL lỗi vào câu hỏi của mình không? Và nếu bạn vẫn chưa sửa lỗi Firefox cho nó, tôi hy vọng bạn có thể vui lòng cân nhắc dành thời gian để thực hiện việc đó.
sidehowbarker

@sideshowbarker Tôi đã truy cập vào địa chỉ báo cáo lỗi firefox và không thành công. Vì vậy, tôi đã điền vào khiếu nại " Không thể tìm thấy nơi để báo cáo lỗi " trên đầu vào của firefox (" Firefox đã làm tôi buồn. ") Và bỏ cuộc. Nếu bạn biết nơi để báo cáo lỗi (và đó là quy trình báo cáo thực tế, không phải một số thông tin phản hồi của người dùng), vui lòng cho tôi biết. Đây không phải là lần đầu tiên tôi phát hiện ra vấn đề mà tôi có thể tái tạo và xác định một cách đáng tin cậy là chỉ dành cho firefox.
Tomáš Zato - Phục hồi Monica

1
Yeah đã đồng ý rằng họ không nói rõ ràng hết mức có thể. Dù sao, đối với lỗi cụ thể này, vui lòng sử dụng bugzilla.mozilla.org/… Điều đó sẽ nâng nó lên so với DOM: Workersthành phần bugzilla thích hợp trong Coresản phẩm bugzilla thích hợp .
sidehowbarker

1
Để cố gắng giúp những người khác tránh những sự thất vọng tương tự như bạn đã gặp phải khi cố gắng tìm ra nơi để báo cáo lỗi công cụ trình duyệt Firefox, tôi đã tạo stackoverflow.com/questions/33059442/… Nếu bạn nghĩ rằng sẽ hữu ích khi lưu thông tin đó tại đây trong StackOverflow, vui lòng xem xét ủng hộ nó (nếu không nó có thể có nguy cơ bị xóa nếu những người phản đối đầu gối tay chân khác nhảy vào nhóm).
sidehowbarker

1
Mô hình là chậm có chủ đích. Cách hiệu quả hơn nhiều để làm là bỏ qua các lookahead và thay vào đó sử dụng mảng refference. Nhưng câu hỏi này thực sự không phải về việc viết mã tối ưu.
Tomáš Zato - Phục hồi Monica

Câu trả lời:


2

Sau một loạt các bài kiểm tra, tôi xác nhận rằng đây là Mozilla Firefox (nó ảnh hưởng đến tất cả các phiên bản máy tính để bàn Windows mà tôi đã thử). Với Google Chrome, Opera hoặc thậm chí Firefox dành cho thiết bị di động, các kết quả khớp regexp diễn ra giống nhau, có công nhân hay không.

Nếu bạn cần khắc phục sự cố này, hãy nhớ bỏ phiếu cho báo cáo lỗi trên bugzilla . Tôi sẽ cố gắng bổ sung thêm thông tin nếu có gì thay đổi.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.