Nauczyłem się z książek, które powinieneś pisać dla pętli w ten sposób :
for(var i=0, len=arr.length; i < len; i++){
// blah blah
}
więc arr.length
nie będzie to obliczane za każdym razem.
Inni twierdzą, że kompilator dokona optymalizacji, więc możesz po prostu napisać:
for(var i=0; i < arr.length; i++){
// blah blah
}
Chcę tylko wiedzieć, który jest najlepszy sposób w praktyce?
javascript
performance
loops
wong2
źródło
źródło
for ... of
pętlę do tego konkursu? Składnia wydaje się jeszcze łatwiejsza niż pętla for bez buforowania i chcę wiedzieć, czy powinienem przejść na używanie pętli for.Odpowiedzi:
Po wykonaniu tego testu w większości nowoczesnych przeglądarek ...
http://jsben.ch/dyM52
Obecnie najszybsza forma pętli (i moim zdaniem najbardziej syntaktycznie oczywista).
standard pętli z buforowaniem długości
Powiedziałbym, że to zdecydowanie przypadek, w którym pochwalam programistów silnika JavaScript. Czas pracy powinien być zoptymalizowany dla jasności , a nie sprytu .
źródło
++i
.for(var i=0, len=myArray.length; i<len; ++i)
sprawdź jsperf.com/caching-array-length/84var
instrukcji. Sposób, w jaki jest napisany,len
zależy od tego, jak sugerujesz.Absolutnie najszybszym sposobem na przejście przez tablicę javascript jest:
Zobacz pełne porównanie na http://blogs.oracle.com/greimer/entry/best_way_to_code_a
źródło
var
(inaczejlen
staje się zmienną globalną). Zobacz także jsperf.com/loops, aby uzyskać więcej testów porównawczych pętli.Począwszy od czerwca 2016 r. , Przeprowadzając niektóre testy w najnowszym Chrome (71% rynku przeglądarek w maju 2016 r. I stale rośnie):
Wierzę, że ten wątek jest za stary i programiści wprowadzają w błąd, myśląc, że muszą buforować długość lub używać odwrotnych przejść z dekrementami w celu uzyskania lepszej wydajności, pisząc kod, który jest mniej czytelny i bardziej podatny na błędy niż prosta prosta pętla for. Dlatego polecam:
Jeśli aplikacja iteruje wiele elementów lub kod pętli znajduje się w często używanej funkcji, bezpośrednią odpowiedzią dla pętli jest odpowiedź:
Jeśli twoja aplikacja tak naprawdę nie wykonuje iteracji przez wiele elementów lub po prostu musisz wykonywać małe iteracje tu i tam, użycie standardowego wywołania zwrotnego forEach lub dowolnej podobnej funkcji z wybranej biblioteki JS może być bardziej zrozumiałe i mniej podatne na błędy, ponieważ zakres zmiennej indeksu jest zamknięty i nie trzeba używać nawiasów, uzyskując bezpośredni dostęp do wartości tablicy:
Jeśli naprawdę potrzebujesz zarysować kilka milisekund podczas iteracji ponad miliardów wierszy, a długość tablicy nie zmienia się w trakcie procesu, możesz rozważyć buforowanie długości w pętli for. Chociaż myślę, że obecnie nie jest to naprawdę konieczne:
źródło
for(let i=0, j=array.length; i < j; i++)
znacznie przyspieszysz przesyłanie do przodu dla pętli. W kilku testach przeprowadziłem, że wygrał, w większości mieścił się w granicach błędu lub pętli zwrotnej.Jeśli zamówienie nie jest ważne, wolę ten styl:
Buforuje długość i jest znacznie krótszy do napisania. Ale będzie iterować po tablicy w odwrotnej kolejności.
źródło
i--
Zwraca liczbę, a gdy liczba jest0
warunkiem, tofalse
dlatego, żeBoolean(0) === false
.To tylko 2018, więc aktualizacja może być przyjemna ...
I naprawdę muszę się nie zgodzić z przyjętą odpowiedzią . Odracza się w różnych przeglądarkach. niektóre robią
forEach
szybciej, niektórefor-loop
, a niektórewhile
są testem porównawczym dla wszystkich metod http://jsben.ch/mW36ea ponieważ można zobaczyć wiele for-loop,
for(a = 0; ... )
warto wtedy wspomnieć, że bez zmiennych zmienne będą definiowane globalnie, co może dramatycznie wpłynąć na szybkość, więc będzie wolniej.Urządzenie Duffa działa szybciej w operze, ale nie w Firefoxie
źródło
2014
While
powracaPo prostu myśl logicznie.
Spójrz na to
for
pętla 3 parametryPowiedz mi teraz, dlaczego powinno to być szybsze niż:
while
ma tylko jeden parametrByłem całkowicie zdezorientowany, gdy Chrome 28 pokazał, że pętla for jest szybsza niż w tym czasie. To musi mieć ben
„Uh, wszyscy używają pętli for, skupmy się na tym podczas programowania dla chrome”.
Ale teraz, w 2014 r., Pętla while wraca do Chrome. jest 2 razy szybszy, w innych / starszych przeglądarkach zawsze był szybszy.
Ostatnio zrobiłem kilka nowych testów. Teraz, w środowisku rzeczywistym, te krótkie kody są nic nie warte, a jsperf nie może właściwie wykonać poprawnie pętli while, ponieważ musi odtworzyć długość tablicy. Zajmuje to również trochę czasu.
nie możesz uzyskać rzeczywistej prędkości pętli while na jsperf.
musisz stworzyć własną funkcję niestandardową i sprawdzić to za pomocą
window.performance.now()
I tak ... nie ma mowy, żeby pętla while była po prostu szybsza.
Na przykład mam scenę płótna, w której muszę obliczyć współrzędne i kolizje ... odbywa się to między 10-200 mikrosekund (nie w milisekundach). tak naprawdę renderowanie wszystkiego zajmuje kilka milisekund. Tak samo jak w DOM.
ALE
Istnieje inny bardzo wydajny sposób,
loop
w niektórych przypadkach użycie for ... na przykład do kopiowania / klonowania tablicyZwróć uwagę na ustawienie parametrów:
Powiedział to, że potwierdza to, że maszyny takie jak -
pisząc, że chciałem zrobić to trochę krócej i usunąć trochę niepotrzebnych rzeczy i napisałem ten w tym samym stylu:
Nawet jeśli jest krótszy, wygląda na to, że użycie jeszcze
i
jednego czasu wszystko spowalnia. Jest o 1/5 wolniejszy niż poprzedniafor
iwhile
pierwsza pętla .Uwaga:
;
jest bardzo ważne po za looo bez{}
Nawet jeśli właśnie powiedziałem, że jsperf nie jest najlepszym sposobem testowania skryptów .. dodałem tutaj 2 pętle
http://jsperf.com/caching-array-length/40
A oto kolejna odpowiedź na temat wydajności w javascript
https://stackoverflow.com/a/21353032/2450730
Ta odpowiedź ma pokazać skuteczne sposoby pisania javascript. Więc jeśli nie możesz tego przeczytać, zapytaj, a otrzymasz odpowiedź lub książkę o javascript http://www.ecma-international.org/ecma-262/5.1/
źródło
for
było to szybsze niżwhile
kiedyś, i kiedyś czytałem w crome-dev, że właśnie z tego powodu wspomniałeś. Byłoby tylko kwestią czasu, zanimwhile
znów to nadrabi. Od tego momentu logika w pierwszej części twojej odpowiedzi będzie obowiązywała (jeszcze raz, tak)! Jednak nowoczesne implementacje nie podążają już sztywno za każdym krokiem określonym w ecma (optymalizują). Ponieważ teraz twój silnik nie jest już najbardziej zauważalnym wąskim gardłem, możesz teraz zauważyć brak pamięci podręcznej procesora w pętlach zwrotnych !http://jsperf.com/caching-array-length/60
Najnowsza wersja testu, którą przygotowałem (wykorzystując ponownie starszą), pokazuje jedną rzecz.
Długość buforowania nie jest tak ważna, ale nie szkodzi.
Każde pierwsze uruchomienie powyższego testu (na świeżo otwartej karcie) daje najlepsze wyniki dla 4 ostatnich fragmentów (3, 5, 7 i 10 na wykresach) w Chrome, Opera i Firefox w moim Debian Squeeze 64-bitowym ( mój komputer stacjonarny) ). Kolejne przebiegi dają całkiem inny wynik.
Wnioski dotyczące wydajności są proste:
!==
zamiast<
.shift()
tablica niszcząca jest również wydajna.tl; dr
Obecnie (2011.10) poniższy wzór wydaje się najszybszy.
Pamiętaj, że buforowanie
arr.length
nie jest tutaj kluczowe, więc możesz po prostu sprawdzić,i !== arr.length
czy wydajność nie spadnie, ale otrzymasz krótszy kod.PS: Wiem, że we fragmencie z
shift()
jego wynikiem można było użyć zamiast dostępu do 0-tego elementu, ale jakoś przeoczyłem to po ponownym użyciu poprzedniej wersji (która miała błędne pętle while), a później nie chciałem stracić już uzyskanych wyników.źródło
„Najlepszy” jak w czystej wydajności? lub wydajność ORAZ czytelność?
„Najlepsza” czysta wydajność to ta, która wykorzystuje pamięć podręczną i operator prefiksu ++ (moje dane: http://jsperf.com/caching-array-length/189 )
Twierdziłbym, że pętla for bez pamięci podręcznej zapewnia najlepszą równowagę między czasem wykonania a czasem odczytu programisty. Każdy programista, który zaczął od C / C ++ / Java, nie zmarnuje ms na przeczytanie tego
źródło
len
się nazywa, zawsze trzeba będzie wykonać podwójne podejście do pierwszej pętli. Zamiar drugiej pętli jest oczywisty.** buforuj długość tablicy w pętli, uniknie się kilku sekund. Zależy od elementów w tablicy, jeśli jest więcej elementów w tablicy, istnieje znacząca różnica w odniesieniu do Ms *
**
**
**
**
źródło
To zdecydowanie najszybszy sposób ...
Weź pod uwagę, że spowoduje to zużycie tablicy, zjedzenie jej i pozostawienie niczego ...
źródło
arr.shift();
zamiast,arr.pop()
aby uniknąć odwrócenia tablicy.To rok 2017 .
Zrobiłem kilka testów.
https://jsperf.com/fastest-way-to-iterate-through-an-array/
Wygląda na to, że
while
metoda jest najszybsza w Chrome.Wygląda lewej zmniejszania (
--i
) jest znacznie szybciej niż inni (++i
,i--
,i++
) na Firefox.Takie podejście jest średnio na czczo. Ale iteruje tablicę w odwrotnej kolejności.
Jeśli ważne jest zlecenie forward, skorzystaj z tego podejścia.
źródło
let
, faktycznie porównujesz wydajność tworzenia zakresu zamiast wydajności pętli. Użycielet i = 0, ii = array.length
w twoichfor
pętlach stworzy nowy zakres dla tych zmiennych wewnątrzfor
bloku. Twojewhile
przykłady nie tworzą nowego zakresu dla zmiennych wewnątrzwhile
bloku i dlatego są one szybsze. Jeśli użyjeszvar
zamiastlet
w pętli for, zobaczysz, jak pętle są nadal tak szybkie jak w 2017 roku, ale bardziej czytelne.var
ilet
mają taką samą wydajność - stackoverflow.com/a/32345435/1785975while
bycie szybszym w Chrome” nie jest trafne. Tylko w przypadku używanialet
ze względu na problemy z wydajnością tego słowa kluczowego w Chrome. Jeśli używaszvar
lub z innymi przeglądarkamifor
iwhile
są one prawie takie same, czasamifor
jest nawet szybsze w zależności od testu porównawczego, i jest bardziej kompaktowy i czytelny imho.Zawsze piszę w pierwszym stylu.
Nawet jeśli kompilator jest wystarczająco inteligentny, aby zoptymalizować go pod kątem tablic, ale nadal jest inteligentny, jeśli używamy tutaj DOMNodeList lub jakiegoś skomplikowanego obiektu o obliczonej długości?
Wiem, jakie jest pytanie o tablice, ale myślę, że dobrą praktyką jest pisanie wszystkich pętli w jednym stylu.
źródło
i ++ jest szybszy niż ++ i, --i i i--
Możesz także zapisać ostatnią linię, wykonując arr [i ++], kiedy ostatni raz potrzebujesz dostępu do i (ale może to być trudne do debugowania).
Możesz to przetestować tutaj (z innymi testami pętli): http://jsperf.com/for-vs-whilepop/5
źródło
++i
jest szybszy ...We wrześniu 2017 r. Te testy jsperf pokazują następujący wzorzec, który jest najbardziej wydajny w Chrome 60:
Czy ktoś może się rozmnażać?
źródło
Próbowałem innych sposobów na iterację ogromnej tablicy i odkryłem, że zmniejszenie o połowę długości tablicy, a następnie iteracja obu połówek w jednej pętli jest szybsze. Tę różnicę wydajności można zobaczyć podczas przetwarzania ogromnych tablic .
Pewne porównanie wydajności (przy użyciu timer.js) między buforowaną długością pętli for VS a powyższą metodą.
http://jsfiddle.net/tejzpr/bbLgzxgo/
źródło
Kolejny test jsperf.com: http://jsperf.com/while-reverse-vs-for-cached-length
Pętla rewersyjna wydaje się być najszybsza. Jedynym problemem jest to, że podczas gdy (--i) zatrzyma się na 0. Jak mogę wtedy uzyskać dostęp do tablicy [0] w mojej pętli?
źródło
while (i--)
prawdziwośći
zostanie przetestowana przed zmniejszeniem, a nie zmniejszeniem, a następnie sprawdzeniem prawdziwości.Podstawowa pętla while jest często najszybsza. jsperf.com to świetna piaskownica do testowania tego rodzaju koncepcji.
https://jsperf.com/fastest-array-loops-in-javascript/24
źródło
Podczas gdy pętla jest nieco szybsza niż dla pętli.
Zamiast tego użyj pętli while
źródło
Najszybsze podejście to tradycyjna pętla. Oto bardziej wszechstronne porównanie wydajności.
https://gists.cwidanage.com/2019/11/how-to-iterate-over-javascript-arrays.html
źródło
Najbardziej eleganckim rozwiązaniem, jakie znam, jest użycie mapy.
źródło
Spróbuj tego:
źródło
Szybszym sposobem zapętlenia tablicy jest użycie filtra. Metoda filter () tworzy nową tablicę ze wszystkimi elementami, które pomyślnie przejdą test zaimplementowany przez podaną funkcję.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter
Z mojego doświadczenia zawsze wolę filtry, mapę itp.
źródło
Począwszy od 2019 roku WebWorker stał się bardziej popularny, w przypadku dużych zestawów danych możemy używać WebWorker do przetwarzania znacznie szybciej dzięki pełnemu wykorzystaniu procesorów wielordzeniowych.
Mamy również plik Parallel.js, dzięki któremu WebWorker jest znacznie łatwiejszy w użyciu do przetwarzania danych.
źródło