Подтвердить что ты не робот

Что Chrome делает мгновенно, Firefox занимает 30 секунд

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

Теперь я понимаю, что разные браузеры реализуют 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; }
}
4b9b3361

Ответ 1

Я думаю, это потому, что на каждом вызове .read() вы делаете content.slice(1) и каждый раз, когда он копирует всю строку, но первый символ, и может занять много времени. Попробуйте изменить свой класс 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; }
}

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

Ответ 2

Заметил, что вы используете свободное равенство. Я бы начал там и изменил value == на === и посмотрел, не изменилось ли оно.

Вот jsperf of free vs strict: http://jsperf.com/performance-of-loose-vs-strict-equality