Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/385.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript Chrome即时完成的功能,Firefox需要30秒_Javascript_Performance - Fatal编程技术网

Javascript Chrome即时完成的功能,Firefox需要30秒

Javascript Chrome即时完成的功能,Firefox需要30秒,javascript,performance,Javascript,Performance,目前,我正在创建一个程序,将源代码转换为突出显示的HTML文本。不过,当我测试它时,我发现了一些奇怪的结果。在Chrome上,程序几乎会在瞬间解析1000行源代码。然而,Firefox需要30秒来解析同样的1000行代码。讽刺的是,IE10只需要18秒 现在,我知道不同的浏览器实现javascript的方式不同,而且Chrome往往更快,但我不明白为什么它要比Firefox长30倍。我对每个操作运行了1000000000次原始while循环测试,耗时14秒,耗时12秒。因此,我倾向于相信我的代码

目前,我正在创建一个程序,将源代码转换为突出显示的HTML文本。不过,当我测试它时,我发现了一些奇怪的结果。在Chrome上,程序几乎会在瞬间解析1000行源代码。然而,Firefox需要30秒来解析同样的1000行代码。讽刺的是,IE10只需要18秒

现在,我知道不同的浏览器实现javascript的方式不同,而且Chrome往往更快,但我不明白为什么它要比Firefox长30倍。我对每个操作运行了1000000000次原始while循环测试,耗时14秒,耗时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;
}

我认为这是因为在每次调用
.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; }
}

我认为它可以解决所有浏览器的速度问题。

注意到您使用的是松散相等。我将从这里开始,将==改为===并看看它是否有区别


这里是松散与严格的jsperf:

你能告诉我们REs是什么样子的吗(
开始
结束
)?ostream.write在哪里?到字符串或直接到DOM,等等?可能不是原因,但一个快速的改变是将多个
istream.peek()
调用移动到
do
语句之前的单个调用。根据我的经验,FireFox是最慢的浏览器。我在几个项目中工作过,在过去的几年和几个版本中,FireFox一直明显比IE和Chrome慢。虽然Chrome在大多数情况下速度更快,但有时候IE的表现要比Chrome好得多,但在我多年的经验中,我不记得FireFox比IE好,当然我很确定我从来没有见过它比Chrome好。如果有区别的话,它实际上使用的是
+=
。事实证明,消除ostream.write()非常困难,因为它对循环的功能至关重要。将其替换为一个简单的计数器,在每次调用函数时循环10次,现在需要FF 26秒,Chrome略多于1秒。因此,似乎连接的行为可能是一个促成因素,但另一个因素正在发生。我想这仅仅是循环运行的原始次数,但是我执行的while循环测试表明FF和Chrome应该是相似的,所以我不知所措。
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; }
}