对于javascript中的循环速度性能

时间:2011-02-04 21:32:00

标签: javascript loops for-loop performance

我经历了http://www.youtube.com/watch?v=mHtdZgou0qU加速你的javascript。

所以我做了个人速度测试:

    var count = 50000000;
    var testDummy;

    // test 1
    testDummy = 0;
    var test1Start = new Date().getTime();
    var i;
    for (i=0;i<count;i++) {
        testDummy++;
    }
    var test1End = new Date().getTime();
    var test1Total = (test1End-test1Start);

    // test 2
    testDummy = 0;
    var test2Start = new Date().getTime();
    var i
    for (i=count; i--;) {
        testDummy++;
    }
    var test2End = new Date().getTime();
    var test2Total = (test2End-test2Start);


    debug(
      "test1\n" + 
      "total: " + test1Total + "\n" + 
      "test2\n" + 
      "total: " + test2Total 
    );

我没有得到显着的结果,有时它们甚至有时都没有。

我的问题是,如果我像这样使用循环:“for(i=count;i--;)”它真的更快吗? 我在测试中做错了什么。

感谢您的帮助!

4 个答案:

答案 0 :(得分:4)

(我把它写成评论,但是时间太长了。)

首先:担心for循环的效率几乎总是浪费(你自己的)时间。循环内部通常对性能的影响远大于指定循环的细节。

第二:你测试了哪些浏览器?不同的浏览器会显示不同的性能配置即使是同一浏览器的不同版本也会有所不同。

第三:JavaScript引擎优化你的循环并不是不可能的。 JavaScript编译器可以简单地查看循环并决定将testDummy设置为50000000并完成它。

第四:如果你真的想在性能上分一杯羹,我会尝试for(i=count; --i != 0;)以及for(i=count;i--;)。前者可以保存一两个机器指令,因为执行减法(在预先递增步骤中)可能会自动设置一个硬件标志,指示结果为0.当您使用postdecrement运算符时,该标志可能会被浪费,因为它不会直到下一次迭代开始才检查。 (您可以注意到差异的可能性很小甚至没有。)

答案 1 :(得分:3)

嗯...

for( i=0 ; i < len ; i++ )

几乎与

相同
for( i = len ; i-- ; )

让我们描述一下:

案例1: 让我成为0 布尔表达式
让我成为i + 1

案例2: 让我成为len 让我成为我 - 1 将i转换为boolean(键入coersion)并解释它。

差异应该是微小的,完全取决于类型coersion与普通布尔表达式的比较效率。

顺便说一句,测试一下:]

var i = count;
while( i-- ) {}

答案 2 :(得分:0)

您的测试没有任何问题。

您正在测试的块非常接近相同,这意味着执行速度的差异将是微不足道的。在两个示例中,变量(i)被设置为固定值并循环直到其达到固定值(计数)。唯一不同的是i ++和i--,就速度而言,我认为实际上是相同的。

你需要注意的事情(不要这样做)是计算循环定义中的“循环直到”值。

答案 3 :(得分:0)

我也做过一些测试,结果如下。

在许多文章中,书籍作者提出“优化”循环更快。

现代浏览器似乎对“正常”循环有一些优化。

Firefox 13.0.1

  • 正常循环:0.887
  • Opt1:1.025
  • Opt2:1.098
  • Opt3:1.399

Chrome 19.0.1

  • 普通循环:3.349
  • Opt1:3.12
  • Opt2:3.109
  • Opt3:3.095

IE8

  • 超过12秒...
  • 在测试期间反复坠毁。

<script type="text/javascript">

function p(p) { console.log(p); }
// function p(p) { document.write(p); }

var testFn = function(num, niz, fn) {
    var start = new Date().getTime();

    fn(num, niz);

    var result = (new Date().getTime() - start) / 1000;

    return result;
}

function normalLoop(num, niz) {
    for (var i = 0; i < niz.length; i++) {
        niz[i] = 'a' + i;
    }
}

function opt1(num, niz) {
    var len = niz.length;
    for (var i = 0; i < len; i++) {
        niz[i] = 'a' + i;
    }
}

function opt2(num, niz) {
    for (var i = niz.length; i--;) {
        niz[i] = 'a' + i;
    }
}

function opt3(num, niz) {
    while(i--) {
        niz[i] = 'a' + i;
    }
}

var niz = [];

var num = 10000000;

for (var i = 0; i < num; i++) { niz.push(i); };

p('Normal Loop: ' + testFn(num, niz, normalLoop));
p('Opt1: ' + testFn(num, niz, opt1));
p('Opt2: ' + testFn(num, niz, opt2));
p('Opt3: ' + testFn(num, niz, opt3));

</script>