2011-12-20 14 views
7
var arr=[]; 
var k; 
for(var i=0;i<5000;i++) 
arr[i]=i; 

console.time("native loop"); 
var len=arr.length; 
for(var j=0;j<len;j++) 
k=arr[j]; 
console.timeEnd("native loop"); 

console.time("jq loop"); 
$(arr).each(function(i,el){ 
k=el; 
}); 
console.timeEnd("jq loop"); 

Generuje, 14ms dla natywnej pętli i 3ms dla Jquery each.jquery each vs. native dla

Używam Jquery 1.6.2. Jeśli Jquery używa natywnej pętli za sceną, to dlaczego to możliwe?

+1

brzmi jak coś jest nie tak - czy wielokrotnie uruchamiałeś ten benchmakr, aby potwierdzić wyniki? czy mógłbyś go wypróbować z kolejnymi iteracjami (500k)? – oezi

+1

To nie pasuje do moich wyników, przeglądarki i liczby uruchomionych testów porównawczych? http: // jsfiddle.net/ambiguous/8V6pk/ –

+0

co się dzieje, gdy uruchamia się każdy pierwszy –

Odpowiedz

8

Myślę, że ma to związek z zakresem zmiennej index - zmienna j jest globalną, która jest o najwolniejszym przypadku zmiennej dostępu. Za każdym razem, gdy twoja pętla musi odwoływać się do j, musi sprawdzić całą drogę łańcucha zasięgu, z powrotem do obiektu globalnego, a następnie pobrać z niego wartość zmiennej.

Otrzymuję podobne liczby w mojej konsoli (Chrome, OS X - 13-15ms dla pętli for, 3-4ms dla jQuery).

Ale, jeśli mogę to zrobić:

(function() { 
    console.time("native loop with function scope"); 
    var len=arr.length; 
    for(var j=0;j++<len;) 
     k=arr[j]; 
    console.timeEnd("native loop with function scope");})() 

on wykonywany w zaledwie 5ms.

Różnica w tym przypadku polega na tym, że j jest zmienną lokalną funkcji, dostępną natychmiastowo, gdy silnik JavaScript wyszukuje zmienne. len jest podobnie lokalny; jedynymi globalnymi w tym przypadku są k i arr.

Aby uzyskać jeszcze większą prędkość z tym zrobić k zmiennej funkcji, zakres i przekazać w arr jako parametr:

(function(arr) { 
    console.time("native loop 2"); 
    var len=arr.length, k; 
    for(var j=0;j++<len;) 
     k=arr[j]; 
    console.timeEnd("native loop 2");})(arr) 

> native loop 2: 0ms 

Dobrze, że to trochę zbyt szybko teraz. Może arr powinien być większy:

var arr=[]; 
for(var i=0;i<50000;i++) 
    arr[i]=i; 

[Try again...] 
> native loop 2: 1ms 

To spowolniło to nieco.

W przypadku macierzy 500 k elementów ten kod działa w 4ms w konsoli JavaScript na moim komputerze. Przy 5M zajmuje to 36 ms.

Należy również zauważyć, że nie używasz surowego wywołania jQuery.each() - najpierw owijasz tablicę w $(), tworząc obiekt jQuery, a następnie wywołując .each na tym. Bardziej uczciwym testem może być wykonanie tego samego testu, który powinien być całkiem zbliżony do czasu drugiego przykładu powyżej. jQuery dodaje trochę narzut; sprawdzanie typów jego argumentów, ale potem uruchamia dość ciasną pętlę.

+0

To trochę rozwiązuje problem. To działa w firefoxie 8 na moim komputerze, ale na chromie statystyki są takie same. W tym też nie działa na dużym zestawie wejściowym. Czy wypróbowałeś go na 500000? –

+0

Na 500000 uruchomiono go w czasie 4 ms, czyli mniej więcej w tym samym czasie, co oryginalny test jQuery z 5000 elementów. W tym momencie doszedłem do wniosku, że większość czasu jQuery spędziłem na przekształceniu tablicy w zawinięty obiekt jQuery. –

+0

Próbowałem wcześniej, ale to samo na mojej maszynie –