这话我听过好几次了。JavaScript循环在向后计数时真的更快吗?如果有,为什么?我已经看到了一些测试套件示例,它们显示反向循环更快,但我找不到任何解释!
我假设这是因为循环不再需要在每次检查属性时评估它是否已经完成,它只检查最终的数值。
即。
for (var i = count - 1; i >= 0; i--)
{
// count is only evaluated once and then the comparison is always on 0.
}
这话我听过好几次了。JavaScript循环在向后计数时真的更快吗?如果有,为什么?我已经看到了一些测试套件示例,它们显示反向循环更快,但我找不到任何解释!
我假设这是因为循环不再需要在每次检查属性时评估它是否已经完成,它只检查最终的数值。
即。
for (var i = count - 1; i >= 0; i--)
{
// count is only evaluated once and then the comparison is always on 0.
}
当前回答
我在jsbench上做了一个比较。
正如alestani指出的那样,在升序循环中需要花费时间的一件事是,对于每次迭代,计算数组的大小。在这个循环中:
for ( var i = 1; i <= array.length; i++ )
每次增加i,你就计算。length。
for ( var i = 1, l = array.length; i <= l; i++ )
当你声明i时,你只对.length求值一次。
for ( var i = array.length; i--; )
比较是隐式的,它发生在i递减之前,并且代码非常可读。然而,你在循环中放入的东西会产生很大的不同。
循环调用函数(在其他地方定义):
for (i = values.length; i-- ;) {
add( values[i] );
}
内联代码循环:
var sum = 0;
for ( i = values.length; i-- ;) {
sum += values[i];
}
如果你可以内联你的代码,而不是调用一个函数,而不牺牲易读性,你可以有一个数量级的速度循环!
注意:由于浏览器越来越擅长内联简单的函数,这实际上取决于你的代码有多复杂。所以,先配置再优化,因为
瓶颈可能在其他地方(ajax, reflow,…) 你可以选择一个更好的算法 您可以选择更好的数据结构
但是请记住:
代码是为了让人阅读而写的,只是顺便让机器执行。
其他回答
帮助别人避免头痛——投票吧!!
本页上最流行的答案在Firefox 14上不工作,并且没有通过jsLinter。while循环需要比较操作符,而不是赋值操作符。它可以在chrome、safari甚至ie浏览器上运行。但在firefox中消亡了。
这个坏了!
var i = arr.length; //or 10
while(i--)
{
//...
}
这会有用的!(在firefox上工作,通过jsLinter)
var i = arr.length; //or 10
while(i>-1)
{
//...
i = i - 1;
}
不是——或++,而是比较操作。使用——,你可以使用与0比较,而使用++,你需要与长度比较。在处理器上,与零的比较通常是可用的,而与有限整数的比较则需要减法。
a++ < length
实际编译为
a++
test (a-length)
所以它在编译时在处理器上花费的时间更长。
使用前缀增量操作符要快一些。对于后缀,编译器必须保留之前的值作为表达式的结果。
for (var i = 0; i < n; ++i) {
do_stuff();
}
聪明的解释器或编译器会看到i++的结果没有被使用,也不会存储表达式的结果,但不是所有的js引擎都这样做。
它取决于数组在内存中的位置,以及访问该数组时内存页面的命中率。
在某些情况下,按列顺序访问数组成员比按行顺序访问快,因为命中率增加了。
我在jsbench上做了一个比较。
正如alestani指出的那样,在升序循环中需要花费时间的一件事是,对于每次迭代,计算数组的大小。在这个循环中:
for ( var i = 1; i <= array.length; i++ )
每次增加i,你就计算。length。
for ( var i = 1, l = array.length; i <= l; i++ )
当你声明i时,你只对.length求值一次。
for ( var i = array.length; i--; )
比较是隐式的,它发生在i递减之前,并且代码非常可读。然而,你在循环中放入的东西会产生很大的不同。
循环调用函数(在其他地方定义):
for (i = values.length; i-- ;) {
add( values[i] );
}
内联代码循环:
var sum = 0;
for ( i = values.length; i-- ;) {
sum += values[i];
}
如果你可以内联你的代码,而不是调用一个函数,而不牺牲易读性,你可以有一个数量级的速度循环!
注意:由于浏览器越来越擅长内联简单的函数,这实际上取决于你的代码有多复杂。所以,先配置再优化,因为
瓶颈可能在其他地方(ajax, reflow,…) 你可以选择一个更好的算法 您可以选择更好的数据结构
但是请记住:
代码是为了让人阅读而写的,只是顺便让机器执行。