2012-03-30 38 views
11

this网站上有一个for循环变体的列表。我可以理解for(var i=0, len=arr.length; i<len ;i++)循环的用法(其中arr是一个数组),因为arr.length不是在每一步都计算出来,所以似乎有一个边际性能增益。然而使用其他变体的优点是什么?例如,循环像For循环javascript中的变化

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

是否有通过使用循环变动不同性能的任何显着的变化?即使是非常大的阵列,我通常也会使用for(var i=0, len=arr.length; i<len ;i++)。所以我只想知道我在这里错过了什么。

+0

“递减”循环在js中快得多。至于最后一个我不会使用它,因为在js false == 0 ==“”。 – mpm 2012-03-30 09:41:43

+0

可能重复的[JavaScript - 循环真的更快...?](http://stackoverflow.com/questions/1340589/javascript-are-loops-really-faster-in-reverse) – Matt 2012-03-30 09:43:21

+1

@camus第二个通过例如循环可能会有用。 DOM元素的集合。 – 2012-03-30 09:45:31

回答

6

它被广泛认为是一个相反的while循环

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

是类似C语言的最快圈型可用的(这也适用于ECMAScript的相当长一段时间,但我认为所有先进即使在今天的标准循环中,日期引擎也很漂亮)。 (jsperf

您的'变化'实际上没有变化,但for-loop中的conditional声明的不同用法(实际上使其成为变体..)。像

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

只需使用条件部分从for-loop做两件事,迭代和检查是否i有truthy值。只要i变为0,循环将结束。

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

这里我们从每次迭代的元素,所以我们可以直接访问循环体内。当你厌倦了总是重复arr[ n ]时,这是常用的。

在循环之前,您在缓存.length属性方面表现不错。正如您正确提到的那样,速度更快,因为我们不必在每次迭代中访问该属性。除此之外,在处理“活结构”(如HTMLCollections)时,DOM脚本中也需要它。

2

的一点是,当你递减迭代器,实际上是比较它与0而非长度,这是因为在更快的“<,< =,>,> =”操作者需要在两个类型检查操作员的左侧和右侧以确定应该使用什么比较行为。

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

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

如果你关心的顺序,您使用的方法是好的。

1

这是每个循环使用不当,因为它会失败的谬误值,打破循环。

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

我也不会使用这个循环(即使强硬它可能会更快......))

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

它看起来令人困惑并且可读性较差,您可能还会在while循环中写入为reverse。

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上。所以看起来“默认”循环毕竟是好的!

+0

这些jsperf测试非常有用。谢谢! – 2012-03-30 11:41:58