Powód jest prosty. Tablica arr
tworzony jest z tym kodem:
var arr = new Array(10000);
Więc to ma długość 10000, ale wszystkie elementy są undefined
. Pętla ta nie działa przy długości tablicy, ale kończy się, gdy napotka „falsy” wartość - przy założeniu, że pętla zostanie zatrzymane, gdy v
odbiera wartość undefined
w wyniku próby odczytu poza końcem tablicy.
Ale w tej konkretnej macierzy, wszystkie dziesięć tysięcy elementy mają wartość undefined
. Tak więc pętla zatrzymuje się, gdy testuje pierwszy element tablicy. Innymi słowy, nie zapętla się wcale! Nic dziwnego, że jest szybki.
Ale co z bardziej rzeczywistą sprawą? W jaki sposób tego rodzaju taryfy pętli z długim tablicy JSON obiektów:
[
{ "id": 507674, "name": "Kolink" },
{ "id": 997356, "name": "DarkLord7854" },
{ "id": 1202830, "name": "Michael Geary" },
/* and thousands more */
]
Tutaj nie ma problemu pętli kończącej natychmiast, ponieważ wszystkie elementy tablicy są „truthy”.
W nowoczesnych silnikach JavaScript ta okazuje się być dość ubogi sposób napisać pętlę, bo niedawno dowiedziałem się do mojego skrajnego zakłopotania.
Byłem jednym z autorów jQuery Cookbook: Napisałem większość z Rozdziału 5, "Szybciej, Prostiej, Więcej Zabawy". Cóż, "szybsza" część nie wypadła tak dobrze.Byłem polecając pętlę bardzo dużo jak twoje do iteracji na dużej tablicy obiektów, takich jak ten powyżej:
for(var item, i = -1; item = array[++i];) {
// do stuff with item
}
Okazuje się, że w nowoczesnych przeglądarkach, to trochę wolniej niż konwencjonalnej pętli takiego:
for(var i = 0, n = array.length; i < n; i++) {
var item = array[i];
// do stuff with item
}
Część to ze względu na fakt, że próbuje odczytać poza końcem tablicy rzuca pewne silniki JavaScript powrotem do deoptimized drodze reprezentujący tablicę, jako jeden z autorów V8 wyjaśnił mi na Google I/O w zeszłym roku. Część tego może być spowodowana przeglądarkami optymalizującymi bardziej powszechne rodzaje pętli i nie optymalizującymi tego mniej powszechnego podejścia.
Albo drogą, pętla bardziej konwencjonalny okazuje się szybciej w nowoczesnych przeglądarek:
http://jsperf.com/mikes-loops/2
Ale to już zupełnie inna sprawa z pętli. W twoim, szalony wzrost wydajności wynika bezpośrednio z faktu, że nie uruchamia on pętli w ogóle. :-)
Ponieważ nic nie robi, prawdopodobnie został zoptymalizowany jako taki przez tłumacza. – Brad
Jakiś rodzaj [Optymalizacji pętli] (http://en.wikipedia.org/wiki/Loop_optimization) obecny w jednym i nieobecny w innych? – FRD
w punkcie widzenia asemblera pętla robi tylko 3 rzeczy: przesuń wskaźnik tablicy o jeden krok w prawo, przetestuj nową wartość, przejdź do początku pętli. można to zrobić szybko. nie mam pojęcia o javascript. :( – scones