在this网站中,有一个for循环变体列表。我可以理解for(var i=0, len=arr.length; i<len ;i++)
循环的用法(其中arr
是一个数组),因为arr.length
未在每个步骤中计算,似乎有一个边际性能增益。但是使用其他变体有什么好处?例如,像
for (var i=arr.length; i--;)
for (var i=0, each; each = arr[i]; i++)
使用不同的for循环变体时,性能是否有明显变化?我通常使用for(var i=0, len=arr.length; i<len ;i++)
即使是非常大的数组。所以我只是想知道我是否遗漏了一些东西。
答案 0 :(得分:7)
人们普遍认为,反向循环
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
属性方面做得很好。正如您正确提到的,它更快,因为我们不必在每次迭代中访问该属性。除此之外,在处理像HTMLCollections
这样的“实时结构”时,DOM脚本中也需要它。
答案 1 :(得分:2)
关键是当你递减迭代器时,你实际上将它与0比较而不是长度,因为“&lt ;,&lt; =,&gt;,&gt; =”运算符需要类型,所以它更快检查操作员的左侧和右侧,以确定应使用哪种比较行为。
最快的循环是:(如果你不关心当然的顺序)
var i = arr.length
while(i--)
{
}
如果您关心订单,那么您使用的方法就可以了。
答案 2 :(得分:2)
根据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上。所以似乎“默认”循环毕竟是好的!!!
答案 3 :(得分:1)
这对于每个循环使用a很少,因为它会在假值上失败,从而打破循环。
for (var i=0, each; each = arr[i]; i++)
我也不会使用这个循环(即使很难,它可能会更快......)
for (var i=arr.length; i--;)
它看起来很混乱,而且可读性较差,你可以在循环时写入反向。