2013-11-20 2 views
17

В настоящее время я создаю программу, которая превратит исходный код в выделенный HTML-текст. Однако, когда я его протестировал, я нашел некоторые странные результаты. В Chrome программа будет обрабатывать 1000 строк источника почти мгновенно. Тем не менее, Firefox занимает 30 секунд для разбора тех же 1000 строк. И, как ни странно, IE10 занимает всего 18 секунд.Что Chrome делает мгновенно, Firefox занимает 30 секунд

Теперь я понимаю, что разные браузеры реализуют javascript по-разному и что Chrome имеет тенденцию быть быстрее, но я не понимаю, почему он берет Firefox более чем в 30 раз дольше. Я проверил сырой тест в течение 10 000 000 000 операций на каждый, и он занял FF 14 секунд и Chrome 12. Поэтому я склонен полагать, что где-то в моем коде есть что-то, что заставляет Firefox делать аномально долгое время; Я провел исследования, но ничего, что я нашел до сих пор, не указывает на большое несоответствие, которое я вижу.

Итак, есть ли какие-либо предложения относительно того, что может быть причиной этого? Я разместил проблемную область кода ниже (комментирование этой части приводит к тому, что оба браузера мгновенно анализируются). start и end - оба регулярных выражения; istream - откуда исходит исходный код, а ostream - это то, где выполняется разобранный код. istream.read() вызывает метод String slice(). Наконец, эта функция называется много раз по всей программе.

function(buffer, istream, ostream){ 
    if(start.test(istream.content)){ 
     buffer = istream.read(); 
     ostream.write('[[span class="' + type + '"]]' + buffer); 
     do{ 
      /* Special Cases */ 
      if(end.test(ostream.content + istream.peek()) && (istream.peek() == "\n" || istream.peek() == " " || istream.peek() == "\t")){ 
       include = true; 
       break; 
      } 
      else if(istream.peek() == "\n"){ 
       istream.read(); 
       ostream.write('[[/span]][[/span]]\n[[span class="line"]][[span class="' + type + '"]]'); 
       continue; 
      } 
      else if(istream.peek() == "\t"){ 
       istream.read(); 
       ostream.write("@<&#160;&#160;&#160;&#160;>@"); 
       continue; 
      } 
      else if(istream.peek() == " "){ 
       istream.read(); 
       ostream.write("@<&#160;>@"); 
       continue; 
      } 
      ostream.write(istream.read()); 
     } while(!istream.isEmpty() && !end.test(ostream.content)); 

     if(include || istream.isEmpty()) 
      ostream.write('[[/span]]'); 
     else{ 
      var ending = ostream.content.length-1; 
      while(!end.test(ostream.content.substr(ending))) 
       --ending; 
      istream.content = ostream.content.substr(ending) + istream.content; 
      ostream.content = ostream.content.substring(0, ending) + '[[/span]]'; 
     } 
     return true; 
    } 
    return false; 
} 

Любое понимание будет высоко оценен, и если у вас есть какие-либо вопросы о том, как определенные аспекты этого будут реализованы, я обяжет. Заранее спасибо.

Определение IStream и ostream объектов:

function IOstream(init){ 
    this.content = init; 

    this.read = function(){ 
     var tmp = this.content.charAt(0); 
     this.content = this.content.slice(1); 
     return tmp; 
    }; 
    this.peek = function(){ return this.content.charAt(0); }; 
    this.write = function(str){ this.content += str; }; 
    this.isEmpty = function(){ return this.content.length == 0; } 
} 
+1

Можете ли вы показать нам, что УЭ выглядеть ('' start' и end')? – Flimzy

+0

Где идет ostream.write? В строку или непосредственно в DOM и т. Д.? – user2864740

+1

Вероятно, это не причина, но одной быстрой заменой было бы переместить несколько вызовов 'istream.peek()' на один вызов перед вашим оператором 'do'. – Graham

ответ

1

Я думаю, это потому, что на каждом .read() призываю вас сделать content.slice(1) и каждый раз, когда он копирует всю строку, но первый характер и может занять много времени. Попробуйте modifyin своего класса IOStream так:

function IOstream(init){ 
    this.content = init; 
    this.cursor = 0; 

    this.read = function(){ 
     var tmp = this.content.charAt(this.cursor); 
     this.cursor++; 
     return tmp; 
    }; 
    this.peek = function(){ return this.content.charAt(this.cursor); }; 
    this.write = function(str){ this.content += str; }; 
    this.isEmpty = function(){ return this.cursor>=this.content.length; } 
} 

Я думаю, что это решит вашу проблему скорости во всех браузерах.

Смежные вопросы