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

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

即。

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

当前回答

并不是说i比i++快。实际上,它们都一样快。

在升序循环中需要花费时间的是,对于每个i,计算数组的大小。在这个循环中:

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

当你声明i时,你只对.length求值一次,而对于这个循环

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

当你检查i是否<= array.length时,你每次增加i就计算.length。

在大多数情况下,您甚至不应该担心这种优化。

其他回答

这并不依赖于——或++符号,而是取决于你在循环中应用的条件。

例如:如果变量有一个静态值,那么循环会比每次循环都检查条件(比如数组的长度或其他条件)更快。

但是不用担心这种优化,因为这次它的效果是以纳秒为单位衡量的。

使用前缀增量操作符要快一些。对于后缀,编译器必须保留之前的值作为表达式的结果。

for (var i = 0; i < n; ++i) {
  do_stuff();
}

聪明的解释器或编译器会看到i++的结果没有被使用,也不会存储表达式的结果,但不是所有的js引擎都这样做。

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

好吧,我不了解JavaScript,它应该只是一个重新计算数组长度的问题,也许与关联数组有关(如果你只是递减,不太可能需要分配新条目——如果数组是密集的,也就是说。有人可能会为此进行优化)。

在低级汇编中,有一个循环指令,称为DJNZ(如果非零则递减和跳跃)。因此,递减和跳转都在一条指令中,使得它可能比INC和JL / JB略快(递增,如果小于则跳转/如果低于则跳转)。同样,与零比较比与其他数字比较简单。但所有这些都是边缘的,也取决于目标架构(可能会产生不同,例如智能手机上的Arm)。

我没想到这种低级别的差异会对解释语言产生这么大的影响,我只是在回答中没有看到DJNZ,所以我想分享一个有趣的想法。

你现在做的方式不是更快(除了它是一个无限循环,我猜你的意思是做I——。

如果你想让它更快,请:

for (i = 10; i--;) {
    //super fast loop
}

当然,在这么小的循环中你不会注意到它。它更快的原因是因为你在检查i是否为“真”时递减i(当它达到0时,它的计算结果为“假”)