2012-03-30 57 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