WebWorker คำนวณ regexp ที่ช้าจับคู่ช้าลงอย่างมาก (3x) - Firefox เท่านั้น


85

ก่อนอื่นฉันเพิ่งสร้างนิพจน์ทั่วไปที่จะจับคู่พา ธ ไลบรารีภายนอกที่ไม่ซ้ำกันทั้งหมดในรายการไฟล์ส่วนหัวทั้งหมดในโปรเจ็กต์ ฉันถามคำถามเกี่ยวกับการสร้าง regexpเมื่อสัปดาห์ที่แล้ว

ฉันเริ่มเข้าไปยุ่งเพื่อดูว่ามันจะทำงานอย่างไรเมื่ออะซิงโครนัสและเมื่อกลายเป็นคนทำงานบนเว็บ เพื่อความสะดวกและความน่าเชื่อถือฉันได้สร้างไฟล์สากลนี้ที่ทำงานในทั้งสามโหมด:

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

ฉันสร้างไฟล์ทดสอบแทนที่จะวางที่นี่ฉันอัปโหลดบนเว็บโฮสติ้งที่น่าเชื่อถือมาก: สาธิต -ข้อมูลการทดสอบ

สิ่งที่ฉันพบว่าน่าแปลกใจมากคือความแตกต่างอย่างมีนัยสำคัญระหว่างผู้ปฏิบัติงานเว็บและการเรียกใช้เบราว์เซอร์ของ RegExp ผลลัพธ์ที่ฉันได้รับ:

  • Mozilla Firefox
    • [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 ...
}

และผลลัพธ์:

  • Mozilla Firefox
    • [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 ฉัน googled ว่าจะรายงานจุดบกพร่องของ Firefox ได้ที่ไหนและฉันล้มเหลว ดังนั้นฉันจึงกรอกคำร้องเรียน " ไม่พบตำแหน่งที่จะรายงานข้อบกพร่อง " ในอินพุตของ Firefox (" Firefox ทำให้ฉันเสียใจ ") และยอมแพ้ หากคุณทราบตำแหน่งที่จะรายงานข้อบกพร่อง (และเป็นขั้นตอนการรายงานจริงไม่ใช่ข้อเสนอแนะของผู้ใช้) โปรดบอกฉัน นี่ไม่ใช่ครั้งแรกที่ฉันพบปัญหาฉันสามารถสร้างซ้ำและระบุได้ว่าเป็น Firefox เท่านั้น
Tomáš Zato - คืนสถานะ Monica

1
ใช่เห็นด้วยว่าพวกเขาไม่ทำให้ชัดเจนเท่าที่ควร อย่างไรก็ตามสำหรับข้อผิดพลาดนี้โปรดใช้bugzilla.mozilla.org/…ซึ่งจะเพิ่มขึ้นเทียบกับDOM: Workersส่วนประกอบของ bugzilla ที่เหมาะสมในCoreผลิตภัณฑ์bugzilla ที่เหมาะสม
sideshowbarker

1
เพื่อพยายามช่วยให้คนอื่นหลีกเลี่ยงความไม่พอใจแบบเดียวกันกับที่คุณพบโดยพยายามหาว่าจะรายงานจุดบกพร่องของเบราว์เซอร์ของเบราว์เซอร์ Firefox ได้ที่ไหนฉันได้สร้างstackoverflow.com/questions/33059442/…หากคุณคิดว่าการมีข้อมูลบันทึกไว้ที่นี่มีประโยชน์ใน StackOverflow โปรดพิจารณาการเพิ่มคะแนน (มิฉะนั้นอาจมีความเสี่ยงที่จะถูกลบหากผู้ลงคะแนนที่ปิดหัวเข่ารายอื่นกระโดดขึ้นไปบน bandwagon)
sideshowbarker

1
รูปแบบช้าตามวัตถุประสงค์ วิธีที่มีประสิทธิภาพมากขึ้นคือการข้าม lookaheads และใช้ refference array แทน แต่คำถามนี้ไม่ได้เกี่ยวกับการเขียนโค้ดที่ดีที่สุด
Tomáš Zato - คืนสถานะ Monica

คำตอบ:


2

หลังจากการทดสอบหลายครั้งฉันยืนยันว่านี่เป็นปัญหาของMozilla Firefox (มีผลกับเดสก์ท็อป Windows ทุกรุ่นที่ฉันลอง) ด้วย Google Chrome, Opera หรือแม้แต่ Firefox มือถือการจับคู่ regexp ใช้เวลาเท่ากันไม่ว่าจะเป็นคนทำงานหรือไม่

หากคุณต้องการแก้ไขปัญหานี้ให้แน่ใจว่าจะออกเสียงลงคะแนนในรายงานข้อผิดพลาดใน Bugzilla ฉันจะพยายามเพิ่มข้อมูลเพิ่มเติมหากมีอะไรเปลี่ยนแปลง

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.