在他的书中《Even Faster Web Sites》中,史蒂夫·桑德斯(Steve Sounders)写道,改进循环性能的简单方法是将迭代器向0递减,而不是向总长度递增(实际上这一章是由尼古拉斯C.扎卡斯(Nicholas C. Zakas)撰写的)。这种改变可以使每次迭代的复杂度不同,从而节省高达50%的原始执行时间。例如:
var values = [1,2,3,4,5];
var length = values.length;
for (var i=length; i--;) {
process(values[i]);
}
对于for
循环、do-while
循环和while
循环,这几乎是相同的。
我想知道,这是什么原因?为什么递减迭代器会更快?(我对技术背景感兴趣,而不是证明这种说法的基准测试。)
编辑:乍一看,这里使用的循环语法看起来是错误的。没有length-1
或i>=0
,所以让我们澄清一下(我也感到困惑)。
以下是通用的for循环语法:
for ([initial-expression]; [condition]; [final-expression])
statement
initial-expression -
var i=length
首先会执行这个变量声明。
condition -
i--
这个表达式会在每次循环迭代之前被计算。它会在第一次通过循环之前使变量递减。如果这个表达式计算结果为
false
,则循环结束。在JavaScript中,0 == false
,所以如果最终i
等于0
,那么它会被解释成false
,循环也会结束。final-expression
这个表达式在每次循环迭代的末尾被计算(在下一次计算condition之前)。这里不需要这个表达式,因此为空。在for循环中,这三个表达式都是可选的。
这里并不是问题的重点,但由于它有点不太常见,我认为澄清一下会很有趣。另外,它更快的原因可能是因为使用了较少的表达式(0 == false
“技巧”)。
i--
。在递减之前,当 i 为0时,它将变为0(假)。由于该条件具有递减变量本身的副作用,因此在语句中不需要第三个(更改/增加/任何其他)表达式。 - cHaoi--
。 - cHao.length
,递减操作会变得非常慢呢?http://jsperf.com/preincrement-vs-postincrement-vs-predecrement-vs-postde/5 - CodeManX