2013-02-01 3 views
5

Stavo giocando con alcune ottimizzazioni delle prestazioni javascript e ho trovato qualcosa di interessante. Ecco il codice:Prestazioni: utilizzo dell'array nello spazio dei nomi dell'oggetto rispetto all'array locale

function gObject() { 

    this.obj = []; 
    this.LIMIT = 100000; 

    this.doLoopLocal = function() { 
     var o = []; 
     for (var i=0;i<this.LIMIT;i+=1) { 
      o.push(i); 
     } 
     return o; 
    };  

    this.doLoopObject = function() { 
     this.obj = []; 
     for (var i=0;i<this.LIMIT;i+=1) { 
      this.obj.push(i); 
     } 
    }; 
}; 

var g = new gObject(); 

console.time('Using Local array'); 
g.doLoopLocal(); 
console.timeEnd('Using Local array'); 

console.time('Using Object array'); 
g.doLoopObject(); 
console.timeEnd('Using Object array'); 

quando l'eseguo, il registro mi dice che l'uso di vettori locali è più lento rispetto all'utilizzo di matrice definita nello spazio dei nomi oggetto. La differenza è significativa: da 8 a 10 volte! (FF 18.0.1)

Using Local array: 16ms 
Using Object array: 2ms 

uno screenshot: enter image description here

ero sempre dal presupposto che l'utilizzo di oggetti definiti a livello locale all'interno di una funzione è più veloce, ma questo esperimento mostra fraintendetemi. Perché dovrebbe succedere?

AGGIORNAMENTO: Ho provato lo script nella console di Firefox locale e i numeri sono qualcosa che mi aspettavo in primo luogo: l'utilizzo di array locali ha prestazioni migliori rispetto all'array di oggetti. Quindi la vera causa è Firebug che per qualche ragione distorce i numeri e mostra risultati errati. Qualcosa da tenere a mente.

+0

Ho incollato questo codice nella mia console in chrome e l'array locale ha impiegato 2 ms e l'array Object ha impiegato 3 ms .. interessante. Cosa succede se si è scambiato l'ordine, eseguire il locale secondo? –

+0

Ho eseguito anche questo in Chrome e ho ottenuto: "Uso dell'array locale: 1.675 ms Utilizzo dell'array di oggetti: 3.585 ms" la prima volta. Dopo aver ripetuto lo stesso codice per tre volte ricevo "Uso dell'array locale: 2.316 ms Utilizzo dell'array di oggetti: 1.673 ms". Ancora più interessante ... –

+0

L'array locale ha preso 1 ms e l'array di oggetti ha richiesto 6 ms in Chrome per me. –

risposta

1

Come sempre con la magia, la magia giace negli occhi che crede che stia accadendo.
Cosa stai testando qui a proposito? Se dimentichiamo che, nel tuo doLoopObject, non restituisci this.obj, solo testare alcune volte mostra che i risultati sono "casuali", anche peggio: se inverti l'ordine dei test, potrebbero cambiare a seconda del Browser. E i risultati dipenderanno dal tempo di attesa tra due clic. Se aspetti qualche secondo, saranno sempre quasi uguali.
Ora stai attento, su JSPerf, alla velocità con cui i numeri stanno crescendo, e, specialmente su Firefox, la spiegazione diventa abbastanza ovvia: ci sono rallentamenti periodici: il garbage collector viene attivato da tali funzioni di creazione di dati inutili. Quando si innesca, le cifre aumenteranno più lentamente, potrebbe essere per un oggetto o una var locale (non importa). Quello che stai misurando qui è il tempo di garbage collector, NON il tempo push() su una proprietà dell'oggetto rispetto a una variabile locale. Questo spiega perché l'ordine, e il tempo tra una prova e l'altra, cambiano le cose.
Aggiungo che il cambiamento tra due test è troppo grande per concludere qualcosa.

Ma la cosa più importante è che, quando in attesa abbastanza, entrambi i test esegue la stessa su FF/Safari ...

L'unica conclusione che si può trarre da tutto questo è: entrambi i metodi esegue lo stesso.

MA Dal momento che chiunque allocasse così tanto "heap" dovrebbe comunque allocare contemporaneamente, utilizzando il semplice myArray [lastIndex-1] = 0, temo che la vera conclusione sia: questo test non mostra nulla.