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

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

即。

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

当前回答

既然你对这个主题感兴趣,可以看看Greg Reimer关于JavaScript循环基准的博客文章,用JavaScript编写循环的最快方法是什么?:

我为JavaScript中不同的循环编码方式构建了一个循环基准测试套件。现在已经有一些这样的工具了,但是我还没有找到任何一个能够区分原生数组和HTML集合的工具。

您还可以通过打开https://blogs.oracle.com/greimer/resource/loop-test.html对循环进行性能测试(如果JavaScript在浏览器中被NoScript阻塞,则无法工作)。

编辑:

Milan Adamovsky最近创建的基准测试可以在运行时针对不同的浏览器执行。

在Mac OS X 10.6上的Firefox 17.0测试中,我得到了以下循环:

其他回答

简单地说

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

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

++还是——并不重要,因为JavaScript是一种解释型语言,而不是编译型语言。每条指令都翻译成一种以上的机器语言,你不应该关心那些血腥的细节。

那些谈论使用——(或++)来有效使用汇编指令的人是错误的。这些指令适用于整数算术,在JavaScript中没有整数,只有数字。

您应该编写可读的代码。

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

如果你想让它更快,请:

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

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

有时,对代码的编写方式做一些非常小的更改,可能会对代码的实际运行速度产生很大的影响。一个微小的代码更改可能会对执行时间产生很大影响的地方是我们有一个处理数组的for循环。当数组是网页上的元素(如单选按钮)时,这种改变的影响最大,但即使数组是Javascript代码的内部,也值得应用这种改变。

编写for循环来处理数组的常规方法如下:

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

The problem with this is that evaluating the length of the array using myArray.length takes time and the way that we have coded the loop means that this evaluation has to be performed every time around the loop. If the array contains 1000 elements then the length of the array will be evaluated 1001 times. If we were looking at radio buttons and had myForm.myButtons.length then it will take even longer to evaluate since the appropriate group of buttons within the specified form must first be located before the length can be evaluated each time around the loop.

显然,我们不希望数组的长度在处理时发生变化,因此所有这些重新计算长度的操作只是不必要地增加了处理时间。(当然,如果你在循环中有添加或删除数组条目的代码,那么数组大小可以在迭代之间改变,所以我们不能改变测试它的代码)

对于一个大小固定的循环,我们能做的就是在循环开始时计算长度,并将其保存在一个变量中。然后,我们可以测试变量以决定何时终止循环。这比每次计算数组长度要快得多,特别是当数组包含多个条目或是网页的一部分时。

这样做的代码是:

for (var i = 0, var j = myArray.length; i < j; i++) {...

因此,现在我们只计算数组的大小一次,并在每次循环中测试循环计数器是否包含该值的变量。访问这个额外的变量比计算数组的大小要快得多,因此我们的代码将比以前运行得快得多。我们的脚本中只有一个额外的变量。

通常情况下,处理数组的顺序并不重要,只要数组中的所有条目都得到了处理。在这种情况下,我们可以通过去掉刚刚添加的额外变量并以相反的顺序处理数组来使代码稍微快一些。

以最有效的方式处理数组的最终代码是:

for (var i = myArray.length-1; i > -1; i--) {...

这段代码仍然只在开始时计算一次数组的大小,但不是将循环计数器与变量进行比较,而是将其与常量进行比较。由于访问常量比访问变量更有效,并且由于我们的赋值语句比以前少了一个,所以第三个版本的代码现在比第二个版本的效率略高,比第一个版本的效率要高得多。

既然你对这个主题感兴趣,可以看看Greg Reimer关于JavaScript循环基准的博客文章,用JavaScript编写循环的最快方法是什么?:

我为JavaScript中不同的循环编码方式构建了一个循环基准测试套件。现在已经有一些这样的工具了,但是我还没有找到任何一个能够区分原生数组和HTML集合的工具。

您还可以通过打开https://blogs.oracle.com/greimer/resource/loop-test.html对循环进行性能测试(如果JavaScript在浏览器中被NoScript阻塞,则无法工作)。

编辑:

Milan Adamovsky最近创建的基准测试可以在运行时针对不同的浏览器执行。

在Mac OS X 10.6上的Firefox 17.0测试中,我得到了以下循环: