2011-12-20 15 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"); 

Sta generando, 14 ms per loop nativo e 3 ms per Jquery ciascuno.jquery ciascuno vs nativo per

Sto usando Jquery 1.6.2. Se Jquery usa il loop nativo dietro la scena, allora come mai, questo è possibile ??

+1

suona come se qualcosa non andasse - hai eseguito quel benchmakr più volte per dimostrare i risultati? ti piacerebbe provarlo con più iterazioni (500k)? – oezi

+1

Ciò non corrisponde ai miei risultati, a quale browser ea quante volte hai eseguito il tuo benchmark? http: // jsfiddle.net/ambiguo/8V6pk/ –

+0

cosa succede quando esegui ogni primo –

risposta

8

Vorrei pensare che ha a che fare con l'ambito della variabile indice - la variabile j è una società globale, che è di circa il caso più lento di accesso variabile. Ogni volta che il loop deve fare riferimento a j, è necessario controllare la catena dell'oscilloscopio, tornare all'oggetto globale e quindi ottenere il valore della variabile da lì.

Ricevo numeri simili nella mia console (Chrome, OS X - 13-15ms per il ciclo for, 3-4ms per jQuery).

Ma, se faccio questo:

(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");})() 

Esegue in soli 5ms.

La differenza in questo caso è che j è una variabile di funzione locale, disponibile immediatamente in primo luogo il motore JavaScript cerca le variabili. len è analogamente locale; gli unici globals in questo caso sono k e arr.

Per ottenere ancora di più la velocità di questo, fare k una variabile funzione di-campo di applicazione, e passare in arr come parametro:

(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 

Beh, è ​​un po 'troppo veloce ora. Forse arr dovrebbe essere più grande:

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

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

Che ha rallentato un po '.

Con un array di 500 k elementi, questo codice viene eseguito in 4 ms nella console JavaScript sul mio computer. A 5M, ci vogliono 36ms.

Si noti inoltre che non si sta utilizzando una chiamata jQuery.each() non elaborata: si sta prima avvolgendo l'array in $(), creando un oggetto jQuery e quindi chiamando .each su quello. Un test più equo potrebbe essere quello di eseguire

$.each(arr, function(i,el){ 
    k=el; 
}); 

Questo dovrebbe essere abbastanza vicino ai tempi del secondo esempio sopra riportato. jQuery aggiunge un po 'di overhead; controllando i tipi dei suoi argomenti, ma dopo che esegue un ciclo piuttosto stretto.

+0

Questo è in qualche modo risolvere il problema. Questa cosa funziona con firefox 8 sulla mia macchina, ma su chromium le statistiche sono le stesse. Anche in questo, non è efficace sul set di input di grandi dimensioni. Hai provato su 500000? –

+0

Su 500000, è stato eseguito in 4 ms, ovvero all'incirca nello stesso momento del test jQuery originale di 5000 elementi. A quel punto, ho capito che la maggior parte del tempo di jQuery è stato impiegato per convertire la matrice in un oggetto jQuery avvolto. –

+0

L'ho provato prima, ma è lo stesso sulla mia macchina –