JavaScript 循环性能 - 为什么将迭代器递减到 0 比递增更快 [英] JavaScript loop performance - Why is to decrement the iterator toward 0 faster than incrementing

查看:35
本文介绍了JavaScript 循环性能 - 为什么将迭代器递减到 0 比递增更快的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在他的书中 更快的网站 Steve Sounders 写道,提高循环性能的一种简单方法是将迭代器向 0 递减,而不是向总长度递增(实际上该章节是由 Nicholas C. Zakas 编写的).根据每次迭代的复杂性,此更改最多可将原始执行时间节省 50%.例如:

In his book Even Faster Web Sites Steve Sounders writes that a simple way to improve the performance of a loop is to decrement the iterator toward 0 rather than incrementing toward the total length (actually the chapter was written by Nicholas C. Zakas). This change can result in savings of up to 50% off the original execution time, depending on the complexity of each iteration. For example:

var values = [1,2,3,4,5];
var length = values.length;

for (var i=length; i--;) {
   process(values[i]);
}

对于 for 循环、do-while 循环和 while 循环来说,这几乎是相同的.

This is nearly identical for the for loop, the do-while loop, and the while loop.

我想知道这是什么原因?为什么要以如此快的速度递减迭代器?(我对这方面的技术背景感兴趣,而不是对证明这一主张的基准感兴趣.)

I'm wondering, what's the reason for this? Why is to decrement the iterator so much faster? (I'm interested in the technical background of this and not in benchmarks proving this claim.)

乍一看,这里使用的循环语法看起来是错误的.没有 length-1i>=0,所以让我们澄清一下(我也很困惑).

At first sight the loop syntax used here looks wrong. There is no length-1 or i>=0, so let's clarify (I was confused too).

这里是通用的 for 循环语法:

Here is the general for loop syntax:

for ([initial-expression]; [condition]; [final-expression])
   statement

  • initial-expression - var i=length

    首先评估这个变量声明.

    This variable declaration is evaluated first.

    条件 - i--

    这个表达式在每次循环迭代之前被计算.它将在第一次通过循环之前递减变量.如果此表达式的计算结果为 false,则循环结束.在 JavaScript 中是 0 == false 所以如果 i 最终等于 0 它被解释为 false 并且循环结束.

    This expression is evaluated before each loop iteration. It will decrement the variable before the first pass through the loop. If this expression evaluates to false the loop ends. In JavaScript is 0 == false so if i finally equals 0 it is interpreted as false and the loop ends.

    最终表达式

    这个表达式在每次循环迭代结束时进行计算(在下一次condition 计算之前).这里不需要它,它是空的.所有三个表达式在 for 循环中都是可选的.

    This expression is evaluated at the end of each loop iteration (before the next evaluation of condition). It's not needed here and is empty. All three expressions are optional in a for loop.

    for 循环语法不是问题的一部分,但因为它有点不常见,我认为澄清它很有趣.也许它更快的一个原因是,因为它使用的表达式更少(0 == false技巧").

    The for loop syntax is not part of the question, but because it's a little bit uncommon I think it's interesting to clarify it. And maybe one reason it's faster is, because it uses less expressions (the 0 == false "trick").

    推荐答案

    我不确定 Javascript,在现代编译器下这可能无关紧要,但在过去"这段代码:

    I'm not sure about Javascript, and under modern compilers it probably doesn't matter, but in the "olden days" this code:

    for (i = 0; i < n; i++){
      .. body..
    }
    

    会产生

    move register, 0
    L1:
    compare register, n
    jump-if-greater-or-equal L2
    -- body ..
    increment register
    jump L1
    L2:
    

    而反向计数代码

    for (i = n; --i>=0;){
      .. body ..
    }
    

    会产生

    move register, n
    L1:
    decrement-and-jump-if-negative register, L2
    .. body ..
    jump L1
    L2:
    

    所以在循环内部它只执行两个额外的指令而不是四个.

    so inside the loop it's only doing two extra instructions instead of four.

    这篇关于JavaScript 循环性能 - 为什么将迭代器递减到 0 比递增更快的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆