这话我听过好几次了。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,…) 你可以选择一个更好的算法 您可以选择更好的数据结构
但是请记住:
代码是为了让人阅读而写的,只是顺便让机器执行。
其他回答
简单地说
“i——和i++。实际上,它们都需要相同的时间。”
但在这种情况下,当你进行增量操作。处理器计算.length每个时间变量都加1,如果减量..特别是在这种情况下,它只计算一次。length直到得到0。
这个人比较了javascript和很多浏览器中的循环。他还提供了一个测试套件,您可以自己运行这些测试。
在所有情况下(除非我在阅读中遗漏了一个),最快的循环是:
var i = arr.length; //or 10
while(i--)
{
//...
}
这并不依赖于——或++符号,而是取决于你在循环中应用的条件。
例如:如果变量有一个静态值,那么循环会比每次循环都检查条件(比如数组的长度或其他条件)更快。
但是不用担心这种优化,因为这次它的效果是以纳秒为单位衡量的。
使用前缀增量操作符要快一些。对于后缀,编译器必须保留之前的值作为表达式的结果。
for (var i = 0; i < n; ++i) {
do_stuff();
}
聪明的解释器或编译器会看到i++的结果没有被使用,也不会存储表达式的结果,但不是所有的js引擎都这样做。
这只是一个猜测,但这可能是因为处理器更容易将某个值与0 (i >= 0)进行比较,而不是与另一个值(i < Things.length)进行比较。