【问题标题】:What Chrome does instantly, Firefox takes 30 secondsChrome 立即执行的操作,Firefox 需要 30 秒
【发布时间】:2014-09-19 20:43:50
【问题描述】:

目前,我正在创建一个程序,它将源代码转换为突出显示的类似 HTML 的文本。但是,当我对其进行测试时,我发现了一些奇怪的结果。在 Chrome 上,该程序将几乎瞬间解析 1000 行源代码。然而,Firefox 需要 30 秒来解析相同的 1000 行。而且,具有讽刺意味的是,IE10 只需要 18 秒。

现在,我知道不同的浏览器以不同的方式实现 javascript,而且 Chrome 往往更快,但我不明白为什么 Firefox 的时间要长 30 倍以上。我对每个操作进行了 10,000,000,000 次原始 while 循环测试,耗时 FF 14 秒,Chrome 12。因此,我倾向于认为我的代码中的某个地方需要 Firefox 异常长时间才能完成;我已经进行了研究,但到目前为止我没有发现任何迹象表明我看到了巨大的差异。

那么,是否有人对可能导致此问题的原因提出任何建议?我已经发布了下面代码的问题区域(注释掉这部分会导致两个浏览器都立即解析)。 startend 都是正则表达式; 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; }
}

【问题讨论】:

  • 你能告诉我们RE的样子吗(startend)?
  • ostream.write 去哪儿了?到字符串还是直接到 DOM 等?
  • 可能不是原因,但要快速改变的一件事是将多个 istream.peek() 调用移动到 do 语句之前的单个调用。
  • 根据我的经验,FireFox 是最慢的浏览器。我参与过多个项目,FireFox 在几年和版本中一直明显慢于 IE 和 Chrome。虽然 Chrome 在大多数情况下往往更快,但有时 IE 的性能却是出了名的优于 Chrome,但在我多年的经验中,我不记得 FireFox 的性能优于 IE,当然我很确定我从未见过它优于 Chrome。
  • 它实际上使用+=,如果它有所作为的话。事实证明,消除 ostream.write() 很困难,因为它对循环的功能至关重要。在用一个简单的计数器替换它之后,每次调用函数迭代循环 10 次,现在它需要 FF 26 秒,Chrome 略多于 1。因此看起来连接的行为可能是一个促成因素,但还有其他事情是继续。我想这只是循环运行的原始次数,但我执行的 while-loop 测试表明 FF 和 Chrome 应该是相似的,所以我很茫然。

标签: javascript performance


【解决方案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】:

    注意到您使用的是松散相等。我会从那里开始,将 == 更改为 ===,看看它是否有所作为。

    这里是松散与严格的 jsperf:http://jsperf.com/performance-of-loose-vs-strict-equality

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-06-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-02-11
      • 1970-01-01
      • 2015-02-10
      • 1970-01-01
      相关资源
      最近更新 更多