【问题标题】:For loop speed performance in javascript用于 javascript 中的循环速度性能
【发布时间】:2011-02-04 21:31:59
【问题描述】:

我通过 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 循环:“for(i=count;i--;)”真的更快吗? 我在测试中做错了什么吗?

感谢您的帮助!

【问题讨论】:

  • 我觉得你这里有问题,for(i=count;i--;) 没有任何意义...
  • 抱歉,这确实有道理(当它达到 0 次强制转换为 false 时)......但是我看不出这怎么能更快
  • 我想这个想法是不是每次循环迭代(测试,增量)执行两个语句,而是可以将增量步骤组合到测试步骤中,每次迭代只执行一个语句......
  • 第三个参数不存在,所以通常的操作时间被跳过,第二个参数更快,因为没有运算符比较。我的意思是,通常如果你作为第二个参数,i
  • 正如我在回答中提到的,您可能更有可能使用 predecrement 而不是 postdecrement 获得优化。

标签: javascript loops for-loop performance


【解决方案1】:

(我会写这个作为评论,但它太长了。)

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

第二:您使用什么浏览器进行了测试?不同的浏览器会显示不同的性能配置文件;即使是同一浏览器的不同版本也会有所不同。

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

第四:如果您真的想在性能上分心,我会尝试for(i=count; --i != 0;)for(i=count;i--;)。前者可能会节省一两条机器指令,因为执行减法(在预减步骤中)可能会自动设置一个硬件标志,指示结果为 0。当您使用后减运算符时,该标志可能会被浪费,因为它会'直到下一次迭代开始时才被检查。 (您能够注意到差异的可能性微乎其微。)

【讨论】:

  • 我使用 Firefox、Chrome、Internet explorer 8 和 safari 进行测试。感谢您的评论/回答。我需要处理大量数据,并且速度快如闪电。所以性能提升是 50ms-150ms 的重要事件。
  • @developer:你真正处理了多少数据?
  • 好吧,我正在处理大约 200 到 500 个字符串元素(单词)并以多种不同的方式组合单词,然后计算每个组合的频率(您可以将其作为标签云进行比较)。我构建数组以组合倍数大小(2 元组、3 元组等)
  • @developerGuile:那么与其为for 循环而苦恼,不如考虑如何最有效地进行字符串操作。与字符串操作中使用的时间相比,您采用的任何for 循环优化都不太可能引起注意。 (如果您发现其他情况,我真的很想听听!)
【解决方案2】:

嗯……

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

实际上与

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

让我们描述一下:

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

案例 2: 让我成为 len
让我成为我 - 1
将 i 转换为布尔值(类型强制)并解释它。

差异应该很小,完全取决于类型强制与普通布尔表达式相比的效率。

顺便测试一下:]

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

【讨论】:

    【解决方案3】:

    你的测试没有问题。

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

    你必须小心(不要做)的事情是计算循环定义中的“循环直到”值。

    【讨论】:

    • 我试图通过跳过第三个参数并在第二个参数中执行比较步骤来提高速度。这就是 Nicholas C. Zakas 在他的 youtube 视频中所说的,但无法通过我自己重现测试来查看收益。
    【解决方案4】:

    我也做了一些测试,这是结果。

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

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

    火狐13.0.1

    • 正常循环:0.887
    • 选项 1:1.025
    • 选项 2:1.098
    • 选项 3:1.399

    Chrome 19.0.1

    • 正常循环:3.349
    • 选项 1:3.12
    • 选项 2:3.109
    • 选项 3: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>
    

    【讨论】:

      猜你喜欢
      • 2014-03-12
      • 2014-07-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-21
      • 2016-01-12
      • 1970-01-01
      • 2014-01-17
      相关资源
      最近更新 更多