问题 对于javascript中的循环变体


这个 网站有一个for循环变化列表。我可以理解的用法 for(var i=0, len=arr.length; i<len ;i++) 循环(在哪里 arr 是一个数组),因为 arr.length 在每个步骤中都没有计算似乎有一个边际性能增益。但是使用其他变体有什么好处?例如,循环就像

  1. for (var i=arr.length; i--;)
  2. for (var i=0, each; each = arr[i]; i++)

通过使用不同的for循环变化,性能是否有任何明显的变化?我一般用 for(var i=0, len=arr.length; i<len ;i++) 即使是非常大的阵列。所以我只想知道我在这里是否遗漏了一些东西。


5447
2018-03-30 09:26


起源

在js中,“递减”循环要快得多。至于最后一个我不会使用它,因为在js false == 0 ==“”。 - mpm
可能重复 JavaScript - 反向循环真的更快......? - Matt
@camus第二个在循环时很有用。 DOM元素的集合。 - Rob W
这个 jsperf 测试所有循环...... - ManseUK
@ManseUK为JSPerf +1。这是谷歌搜索“jsperf for loops”的第一个结果 - Rob W


答案:


人们普遍认为这是一个颠倒的while循环

var loop = arr.length;
while( loop-- ) {
}

是C语言中最快的循环类型(这也适用于ECMAscript很长一段时间,但我认为所有最新的引擎在今天的标准循环中都非常均匀)。 ( jsperf )

你的“变化”实际上没有变化,只是不同的用法 conditional 内部声明 for-loop (这实际上是一个变种......!)。喜欢

1) for (var i=arr.length; i--;)

只需使用条件部分 for-loop 做两件事,迭代和检查是否 i 有一个真正的价值。尽快 i 变 0 循环结束。

2) for (var i=0, each; each = arr[i]; i++)

这里我们从每次迭代中获取元素,因此我们可以直接访问循环体内的元素。这通常在您厌倦了总是重复时使用 arr[ n ]

你在缓存方面做得很好 .length 循环前的属性。正如您正确提到的,它更快,因为我们不必在每次迭代中访问该属性。除此之外,在处理“实时结构”时,有时也需要DOM脚本 HTMLCollections


6
2018-03-30 09:41





关键是当你递减迭代器时,你实际上将它与0比较而不是长度,这是更快的,因为“<,<=,>,> =”运算符需要在左侧和右侧进行类型检查操作员确定应该使用什么比较行为。

最快的循环是:(如果你不关心当然的顺序)

var i = arr.length
while(i--)
{
}

如果您确实关心订单,那么您使用的方法就可以了。


2
2018-03-30 09:41





根据 jsperf JavaScript中最快的循环类型是

var arr = new Array(10);
var i = 0;
while (i < arr.length) {
 arr[i];
 i++;
};

就在(我的默认循环)之前

var arr = new Array(10);
for (var i = 0; i < arr.length; ++i) {
 arr[i];
};

这是最慢的:

var arr = new Array(10);
arr.forEach(function(x) {
 x;
});

至少在OSX 10.7.3上的Chrome 17上。所以似乎“默认”循环毕竟是好的!


2
2018-03-30 09:50



这些jsperf测试非常有用。谢谢! - Ashwin Krishnamurthy


对于每个循环来说,这是一个很糟糕的使用,因为它会在假值上失败,从而打破循环。

for (var i=0, each; each = arr[i]; i++)

我也不会使用这个循环(即使很难,它可能会更快...)

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

它看起来很混乱,而且可读性较差,你可能会在循环时写入reverse。


1
2018-03-30 09:42