WebWorker, yavaş regexp eşleşmelerini önemli ölçüde daha yavaş (3x) hesaplar - yalnızca firefox


85

İlk olarak, bir projedeki tüm başlık dosyalarının bir listesindeki tüm benzersiz harici kütüphane yollarıyla eşleşecek bir düzenli ifade oluşturdum. Bir hafta önce bu normal ifadeyi yapmakla ilgili bir soru sordum .

Eşzamansız olduğunda ve bir web çalışanı haline geldiğinde nasıl davranacağını görmek için etrafa karışmaya başladım. Kolaylık ve güvenilirlik için üç modda da çalışan bu evrensel dosyayı oluşturdum:

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

Buraya yapıştırmak yerine bir test dosyası oluşturdum, çok güvenilir bir web barındırma alanına yükledim: Demo - Test verileri .

Şaşırtıcı bulduğum şey, web çalışanı ile RegExp'in tarayıcı yürütmesi arasında bu kadar önemli bir fark olması. Aldığım sonuçlar:

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

Ayrıca benim özel normal ifademle, eşzamanlı ve eşzamansız döngü arasındaki farkın önemsiz olduğunu da görebilirsiniz. Önden okuma ifadesi yerine bir eşleşme listesi kullanmayı denedim ve sonuçlar çok değişti. İşte eski işlevdeki değişiklikler:

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

Ve sonuçlar:

  • Mozilla Firefox
    • [WORKER]: Time elapsed:0.062s
    • [WORKER-SYNC]: Time elapsed:0.023s
    • [TIMEOUT]: Time elapsed:12.250s (kendine not: her dakika daha da tuhaflaşıyor)
    • [LOOP]: Time elapsed:0.006s

Hızdaki böyle bir farkı açıklayan var mı?


6
Bunun için bir Firefox hatası açtıysanız, lütfen hata URL'sini sorunuza ekleyebilir misiniz? Ve bunun için henüz bir Firefox hatası vermediyseniz, umarım bunu yapmak için zaman ayırmayı düşünebilirsiniz.
sidehowbarker

@sideshowbarker firefox hatalarını nereye bildireceğimi araştırdım ve başarısız oldum. Bu yüzden firefox girişindeki " Hataların nereye bildirileceğini bulamıyorum " şikayetini doldurdum (" Firefox beni üzdü. ") Ve pes ettim . Hataları nereye bildireceğinizi biliyorsanız (ve bu gerçek rapor prosedürü, kullanıcı geri bildirimi için havuz değil), lütfen bana bildirin. Bu, güvenilir bir şekilde yeniden üretebileceğim ve yalnızca firefox olarak tanımlayabileceğim bir sorun bulduğum ilk sefer olmayacak.
Tomáš Zato - Monica'yı eski durumuna getir

1
Evet, olabileceği kadar açıklığa kavuşturmadıklarına katılıyorum. Her neyse, bu özel hata için lütfen bugzilla.mozilla.org/… kullanın. Bu, onu DOM: Workersuygun bugzilla Coreürünündeki uygun bugzilla bileşenine karşı yükseltecektir .
sidehowbarker

1
Başkalarının Firefox tarayıcı motoru hatalarını nereye bildireceğini bulmaya çalışırken karşılaştığınız aynı sıkıntılardan kaçınmalarına yardımcı olmak için, stackoverflow.com/questions/33059442/… 'yi oluşturdum. Bu bilgiyi burada kayıt altına almanın yararlı olacağını düşünüyorsanız StackOverflow, lütfen yukarı oy vermeyi düşünün (aksi takdirde diğer her şeyi kapatan diğer diz çökertenlerin çoğunluğa atlaması durumunda silinme riski altında olabilir).
sidehowbarker

1
Desen kasıtlı olarak yavaş. Bunu yapmanın çok daha verimli yolu, önden gidenleri atlamak ve bunun yerine referans dizisi kullanmaktır. Ancak bu soru gerçekten optimal kod yazmakla ilgili değil.
Tomáš Zato - Monica'yı yeniden etkinleştir

Yanıtlar:


2

Bir dizi testten sonra, bunun bir Mozilla Firefox sorunu olduğunu doğruladım (denediğim tüm Windows masaüstü sürümlerini etkiliyor). Google Chrome, Opera ve hatta Firefox mobile ile, normal ifade eşleşmeleri, çalışan olsun ya da olmasın yaklaşık olarak aynı sürer.

Bu sorunun çözülmesini istiyorsanız bugzilla'daki hata raporunu oyladığınızdan emin olun . Herhangi bir değişiklik olursa ek bilgi eklemeye çalışacağım.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.