2012-03-30 9 views
11

Na stronie this znajduje się lista odmian pętli for. Rozumiem użycie pętli for(var i=0, len=arr.length; i<len ;i++) (gdzie arr jest tablicą), ponieważ arr.length nie jest obliczany w każdym kroku, wydaje się, że jest to marginalny wzrost wydajności. Jakie są jednak zalety korzystania z innych wariantów? Na przykład, pętle jakWarianty pętli w javascript

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

Czy są jakieś zauważalne zmiany w wydajności przy użyciu różnych wariantów dla pętli? Generalnie używam for(var i=0, len=arr.length; i<len ;i++) nawet w przypadku bardzo dużych tablic. Więc chcę tylko wiedzieć, czy czegoś tu brakuje.

+0

Pętla "dekrementująca" jest znacznie większa w js. jak na ostatni nie będę go używał, ponieważ w js false == 0 == "". – mpm

+0

możliwy duplikat [JavaScript - Czy pętle są naprawdę szybkie w odwrotnej kolejności?] (Http://stackoverflow.com/questions/1340589/javascript-are-loops-really-faster-in-reverse) – Matt

+1

@camus The second jeden może być przydatny podczas przechodzenia przez np. kolekcja elementów DOM. –

Odpowiedz

6

Powszechnie uznaje się, że odwrócona pętla

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

jest najszybszym pętla typu dostępne są w językach C-podobnych (w tym także stosowane do ECMAScript od dłuższego czasu, ale myślę, że wszyscy się do - silniki z datą są dziś nawet na standardowych pętlach). (jsperf)

Twoje „wariacje” są właściwie żadne zmiany, ale po prostu inne wykorzystanie rachunku conditional w for-loop (co faktycznie czyni go variation..doh!). Jak

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

Wystarczy wykorzystuje część warunkową z for-loop zrobić zarówno, iteracja i sprawdzenie czy i ma wartość truthy. Gdy tylko i stanie się 0, pętla się zakończy.

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

Tutaj dostajemy element z każdej iteracji, dzięki czemu możemy bezpośrednio przejść, że w ciele pętli. Jest to powszechnie używane, gdy masz dość powtarzania zawsze arr[ n ].

Dobrze radzisz sobie z buforowaniem właściwości .length przed zapętleniem. Jak już wspominałeś, jest to szybsze, ponieważ nie musimy uzyskiwać dostępu do tej właściwości w każdej iteracji. Poza tym jest to również wymagane w skryptach DOM, gdy mamy do czynienia z "żywymi strukturami", takimi jak HTMLCollections.

2

Chodzi o to, że dekrementujesz iterator, porównujesz go do 0, a nie do długości, która jest szybsza, ponieważ operatory "<, < =,>,> =" wymagają kontroli typów zarówno lewej i prawej strony operatora, aby określić, które zachowanie porównania powinno być stosowane.

najszybciej pętla jest: (Jeśli nie dbają o porządek oczywiście)

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

Jeżeli dbam o porządek, metoda używasz jest w porządku.

1

Jest to słabe użycie a dla każdej pętli, ponieważ zawiedzie na wartościach fałszujących, przerywając pętlę.

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

Ja też nie użyłbym tej pętli (nawet trudne może być szybsze ...)

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

Wygląda na zagmatwany i jest mniej czytelny, możesz równie dobrze napisać jako odwrotną pętlę niż wtedy.

2

Według jsperf najszybszy rodzaj pętli w JavaScript jest

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

tuż przed (domyślną pętla)

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

Mając to jest najwolniejszy:

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

przynajmniej w Chrome 17 w OSX 10.7.3. Wygląda więc na to, że pętla "domyślna" jest w porządku !!!

+0

Te testy jsperf są bardzo przydatne. Dziękuję Ci! –