13

Stavo testando le prestazioni (con timeline di cromo) sui casi se la variabile è stata definita all'interno di una chiusura. Quindi i suoi valori non sarebbero esposti all'utente.JavaScript profiling mystery - variabili di chiusura

Come previsto run_proto_fn eseguito alcune volte più veloce e con garbage collection minime e memoria insufficiente.

Ma run_proto_obj si è verificato esattamente l'opposto, come se fosse costoso avere valori non funzionali nelle proprietà delle proprietà del prototipo dell'oggetto.

Qualcuno può condividere un po 'di chiarezza qui?

SOME = function(){}; 
 
SOME.prototype.exe = function(v){ 
 
\t var x = { 
 
\t \t a:'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, quae repudiandae eveniet cumque consequatur vitae aut. Nisi perspiciatis magnam explicabo optio reprehenderit dignissimos at porro quam, neque dolorum, architecto odit?Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, quae repudiandae eveniet cumque consequatur vitae aut. Nisi perspiciatis magnam explicabo optio reprehenderit dignissimos at porro quam, neque dolorum, architecto odit?Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, quae repudiandae eveniet cumque consequatur vitae aut. Nisi perspiciatis magnam explicabo optio reprehenderit dignissimos at porro quam, neque dolorum, architecto odit?Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, quae repudiandae eveniet cumque consequatur vitae aut. Nisi perspiciatis magnam explicabo optio reprehenderit dignissimos at porro quam, neque dolorum, architecto odit?Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, quae repudiandae eveniet cumque consequatur vitae aut. Nisi perspiciatis magnam explicabo optio reprehenderit dignissimos at porro quam, neque dolorum, architecto odit?', 
 
\t \t b:'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, quae repudiandae eveniet cumque consequatur vitae aut. Nisi perspiciatis magnam explicabo optio reprehenderit dignissimos at porro quam, neque dolorum, architecto odit?Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, quae repudiandae eveniet cumque consequatur vitae aut. Nisi perspiciatis magnam explicabo optio reprehenderit dignissimos at porro quam, neque dolorum, architecto odit?Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, quae repudiandae eveniet cumque consequatur vitae aut. Nisi perspiciatis magnam explicabo optio reprehenderit dignissimos at porro quam, neque dolorum, architecto odit?Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, quae repudiandae eveniet cumque consequatur vitae aut. Nisi perspiciatis magnam explicabo optio reprehenderit dignissimos at porro quam, neque dolorum, architecto odit?Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, quae repudiandae eveniet cumque consequatur vitae aut. Nisi perspiciatis magnam explicabo optio reprehenderit dignissimos at porro quam, neque dolorum, architecto odit?', 
 
\t \t c:'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, quae repudiandae eveniet cumque consequatur vitae aut. Nisi perspiciatis magnam explicabo optio reprehenderit dignissimos at porro quam, neque dolorum, architecto odit?Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, quae repudiandae eveniet cumque consequatur vitae aut. Nisi perspiciatis magnam explicabo optio reprehenderit dignissimos at porro quam, neque dolorum, architecto odit?Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, quae repudiandae eveniet cumque consequatur vitae aut. Nisi perspiciatis magnam explicabo optio reprehenderit dignissimos at porro quam, neque dolorum, architecto odit?Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, quae repudiandae eveniet cumque consequatur vitae aut. Nisi perspiciatis magnam explicabo optio reprehenderit dignissimos at porro quam, neque dolorum, architecto odit?Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, quae repudiandae eveniet cumque consequatur vitae aut. Nisi perspiciatis magnam explicabo optio reprehenderit dignissimos at porro quam, neque dolorum, architecto odit?', 
 
\t }; 
 
\t return x[v]; 
 
}; 
 

 
SOME2 = function(){}; 
 
SOME2.prototype.exe = function(v){ 
 
\t return this.exes[v]; 
 
}; 
 
SOME2.prototype.exes = { 
 
\t a:'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, quae repudiandae eveniet cumque consequatur vitae aut. Nisi perspiciatis magnam explicabo optio reprehenderit dignissimos at porro quam, neque dolorum, architecto odit?Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, quae repudiandae eveniet cumque consequatur vitae aut. Nisi perspiciatis magnam explicabo optio reprehenderit dignissimos at porro quam, neque dolorum, architecto odit?Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, quae repudiandae eveniet cumque consequatur vitae aut. Nisi perspiciatis magnam explicabo optio reprehenderit dignissimos at porro quam, neque dolorum, architecto odit?Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, quae repudiandae eveniet cumque consequatur vitae aut. Nisi perspiciatis magnam explicabo optio reprehenderit dignissimos at porro quam, neque dolorum, architecto odit?Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, quae repudiandae eveniet cumque consequatur vitae aut. Nisi perspiciatis magnam explicabo optio reprehenderit dignissimos at porro quam, neque dolorum, architecto odit?', 
 
\t b:'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, quae repudiandae eveniet cumque consequatur vitae aut. Nisi perspiciatis magnam explicabo optio reprehenderit dignissimos at porro quam, neque dolorum, architecto odit?Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, quae repudiandae eveniet cumque consequatur vitae aut. Nisi perspiciatis magnam explicabo optio reprehenderit dignissimos at porro quam, neque dolorum, architecto odit?Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, quae repudiandae eveniet cumque consequatur vitae aut. Nisi perspiciatis magnam explicabo optio reprehenderit dignissimos at porro quam, neque dolorum, architecto odit?Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, quae repudiandae eveniet cumque consequatur vitae aut. Nisi perspiciatis magnam explicabo optio reprehenderit dignissimos at porro quam, neque dolorum, architecto odit?Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, quae repudiandae eveniet cumque consequatur vitae aut. Nisi perspiciatis magnam explicabo optio reprehenderit dignissimos at porro quam, neque dolorum, architecto odit?', 
 
\t c:'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, quae repudiandae eveniet cumque consequatur vitae aut. Nisi perspiciatis magnam explicabo optio reprehenderit dignissimos at porro quam, neque dolorum, architecto odit?Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, quae repudiandae eveniet cumque consequatur vitae aut. Nisi perspiciatis magnam explicabo optio reprehenderit dignissimos at porro quam, neque dolorum, architecto odit?Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, quae repudiandae eveniet cumque consequatur vitae aut. Nisi perspiciatis magnam explicabo optio reprehenderit dignissimos at porro quam, neque dolorum, architecto odit?Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, quae repudiandae eveniet cumque consequatur vitae aut. Nisi perspiciatis magnam explicabo optio reprehenderit dignissimos at porro quam, neque dolorum, architecto odit?Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, quae repudiandae eveniet cumque consequatur vitae aut. Nisi perspiciatis magnam explicabo optio reprehenderit dignissimos at porro quam, neque dolorum, architecto odit?', 
 
}; 
 
SOME_FN = function(){}; 
 
SOME_FN.prototype.exe = function(v){ 
 
\t var x = { 
 
\t \t a: function(p){this.p1 = p;return this;}, 
 
     b:function(p){this.p2 = p*3;return this;}, 
 
     c:function(p){this.p3 = p*99;return this;}, 
 
    }; 
 
    return x[v].call(this,42); 
 
}; 
 

 
SOME_FN2 = function(){}; 
 
SOME_FN2.prototype.exe = function(v){ 
 
    return this.exes[v].call(this,42); \t 
 
}; 
 
SOME_FN2.prototype.exes = { 
 
    a: function(p){this.p1 = p;return this;}, 
 
    b:function(p){this.p2 = p*3;return this;}, 
 
    c:function(p){this.p3 = p*99;return this;}, 
 
}; 
 

 
var a1 = a2 = a_fn1 = a_fn2 = []; 
 
\t 
 

 
var run_local_obj = function(){ 
 
\t for (var i = 1000000 - 1; i >= 0; i--) { 
 
\t \t x1 = new SOME(); 
 
\t \t x1.exe('a'); 
 
\t \t a1.push(x1); 
 
\t } 
 
}; 
 
var run_proto_obj = function(){ 
 
\t for (var i = 1000000 - 1; i >= 0; i--) { 
 
\t \t x2 = new SOME2(); 
 
\t \t x2.exe('a'); 
 
\t \t a2.push(x2); 
 
\t } 
 
}; 
 
var run_local_fn = function(){ 
 
\t for (var i = 1000000 - 1; i >= 0; i--) { 
 
\t \t x1 = new SOME_FN(); 
 
\t \t x1.exe('a'); 
 
\t \t x1.exe('b'); 
 
\t \t x1.exe('c'); 
 
\t \t a_fn1.push(x1); 
 
\t } 
 
}; 
 
var run_proto_fn = function(){ 
 
\t for (var i = 1000000 - 1; i >= 0; i--) { 
 
\t \t x2 = new SOME_FN2(); 
 
\t \t x2.exe('a'); 
 
\t \t x2.exe('b'); 
 
\t \t x2.exe('c'); 
 
\t \t a_fn2.push(x2); 
 
\t } 
 
};
<button onclick="run_local_obj(this)">local obj</button> 
 
<button onclick="run_proto_obj(this)">proto obj</button> 
 
<button onclick="run_local_fn(this)">local obj FN</button> 
 
<button onclick="run_proto_fn(this)">proto obj</button>


ho sentito una frase:

variabile chiusura viene definita ogni volta che la funzione viene eseguito

ma ancora, I'ts nebbia .

+3

Ho appena eseguito entrambi e non ho visto differenze considerevoli. Hai aggiornato la pagina prima di eseguire il secondo test? Altrimenti, avresti aumentato le dimensioni di 'a1' e' a2' (perché sono dello stesso array) ad una dimensione di circa 2000000 che potrebbe essere la fonte della discrepanza. –

risposta

12

Ho provato a eseguire le misurazioni e in primo luogo quello che ho notato è che è difficile capire cosa sta succedendo semplicemente usando il codice della domanda.

Se eseguo questi test uno alla volta (facendo clic sui pulsanti e osservando la timeline), per ogni risultato successivo i risultati sono molto diversi. Da poche esecuzioni sembrava che il terzo (run_local_fn) fosse in genere più lungo di altri.

Poi ho provato a eseguirli nell'ordine inverso (fare clic sui pulsanti da 4 a 1) e ho ottenuto il risultato completamente diverso - il run_local_obj era il più lungo.

Quindi ho modificato un po 'il codice di test, per poter ottenere risultati stabili.

Codice completo is here, è possibile clonare il repository e testarlo localmente.

Ecco come corro ogni test in Chrome (ho lanciato utilizzando python -m SimpleHTTPServer 8082 all'interno della cartella js-perf-test):

  • Aprire la scheda con http://localhost:8082/perf.html, strumenti di sviluppo aperte
  • Avviare la timeline registrazione
  • Fare clic sul pulsante
  • Attendere i risultati nella console (min/max/medio)
  • Interrompere la registrazione della sequenza temporale

risultati sono stabili e ripetibili (entrambi i tempi e vista temporale), ecco uno dei test:

Allora, cosa fare che vediamo qui è:

1) Il run_proto_obj è il più veloce e run_local_obj è vicino ad esso.

Penso che sia previsto che run_proto_obj sia il più efficiente poiché utilizza l'oggetto definito staticamente con le stringhe. E il motore JS è probabilmente in grado di ottimizzare lo run_local_obj, quindi l'oggetto x viene riutilizzato e non viene creato ogni volta.

2) Il run_local_fn è il più lento.

Qui abbiamo il calcolo locale delle stringhe di oggetti e dinamiche x, più floating parti rispetto ad altri test.

3) Il run_proto_fn è più veloce di run_local_fn, ma più lento delle prime due funzioni.

Penso che anche questo è previsto, l'oggetto con a, b, c è definito solo una volta (quindi è più veloce di run_local_fn).

E confrontando le prime due funzioni, calcola dinamicamente le stringhe risultanti, quindi è più lento.

Ma torniamo alla tua domanda:

Come run_proto_fn attesi correre paio di volte più velocemente e con garbage collection minimi, e bassa heap di memoria. Ma run_proto_obj è riuscito a fare esattamente l'opposto, come se fosse costoso avere valori non funzionali nelle proprietà delle proprietà del prototipo dell'oggetto.

Mi sembra che tu non abbia impostato correttamente l'esperimento. Secondo i risultati sopra, run_proto_obj è in realtà il più veloce.

Aggiornamento: Ho appena provato la stessa prova in Firefox, i risultati sono simili:

  • `run_local_obj '- 344.85ms
  • ` run_proto_obj' - 151.47ms
  • `run_local_fn' - 788.08ms
  • `run_proto_fn' - 265.21ms

il run_proto_obj è il più veloce e run_local_fn è il lento est.