这话我听过好几次了。JavaScript循环在向后计数时真的更快吗?如果有,为什么?我已经看到了一些测试套件示例,它们显示反向循环更快,但我找不到任何解释!

我假设这是因为循环不再需要在每次检查属性时评估它是否已经完成,它只检查最终的数值。

即。

for (var i = count - 1; i >= 0; i--)
{
  // count is only evaluated once and then the comparison is always on 0.
}

当前回答

简单地说

“i——和i++。实际上,它们都需要相同的时间。”

但在这种情况下,当你进行增量操作。处理器计算.length每个时间变量都加1,如果减量..特别是在这种情况下,它只计算一次。length直到得到0。

其他回答

简单地说

“i——和i++。实际上,它们都需要相同的时间。”

但在这种情况下,当你进行增量操作。处理器计算.length每个时间变量都加1,如果减量..特别是在这种情况下,它只计算一次。length直到得到0。

简短的回答

对于普通代码,特别是在像JavaScript这样的高级语言中,i++和i——在性能上没有区别。

性能标准是在for循环和compare语句中的使用。

这适用于所有高级语言,并且基本上独立于JavaScript的使用。解释是最后一行的汇编代码。

详细解释

在循环中可能会出现性能差异。背景是,在汇编代码级别上,您可以看到compare with 0只是一个语句,不需要额外的寄存器。

这种比较是在循环的每一次传递中进行的,可能会导致可测量的性能改进。

for(var i = array.length; i--; )

将被求值为如下的伪代码:

 i=array.length
 :LOOP_START
 decrement i
 if [ i = 0 ] goto :LOOP_END
 ... BODY_CODE
 :LOOP_END

注意,0是一个字面值,或者换句话说,是一个常量值。

for(var i = 0 ; i < array.length; i++ )

将被计算为如下的伪代码(假设是正常的解释器优化):

 end=array.length
 i=0
 :LOOP_START
 if [ i < end ] goto :LOOP_END
 increment i
 ... BODY_CODE
 :LOOP_END

注意,end是一个需要CPU寄存器的变量。这可能会在代码中调用额外的寄存器交换,并且需要在if语句中使用更昂贵的compare语句。

只是我的5美分

对于高级语言来说,可读性(有助于可维护性)作为一种较小的性能改进更为重要。

通常,从数组开始到结束的经典迭代更好。

从数组末端到开始的快速迭代会导致可能不需要的反向序列。

附言

正如在评论中问到的:-i和i-的区别在于i在递减之前或之后的求值。

最好的解释是尝试一下;-)下面是一个Bash示例。

 % i=10; echo "$((--i)) --> $i"
 9 --> 9
 % i=10; echo "$((i--)) --> $i"
 10 --> 9

我想为这个线程贡献最快的JavaScript循环,是跨浏览器的!与反向while循环相比,该循环的性能提高了500%以上。

我的博客:JavaScript中最快的循环

编译器不会缓存。length,因此它没有区别,如果你比较0或。length?我想这对于你正在处理的编译器或解释器是非常特定的。

我想说的是,如果你使用的是一个优化的编译器或解释器,那么你不应该担心这个问题,这是语言开发人员应该担心的问题。

这只是一个猜测,但这可能是因为处理器更容易将某个值与0 (i >= 0)进行比较,而不是与另一个值(i < Things.length)进行比较。