13

Ich habe die Leistung (mit Chrom-Timeline) auf Fälle getestet, wenn Variable in einem Abschluss definiert. So werden die Werte dem Benutzer nicht angezeigt.Javascript Profiling Mystery - Closure-Variablen

Wie erwartet run_proto_fn laufen Sie einige Male schneller und mit minimalen Garbage Collections und wenig Speicher Heap.

Aber run_proto_obj passiert, genau das Gegenteil zu machen, als ob es teuer wäre, nicht-Funktion Werte bei Objektprototypen Eigenschaften.

Kann jemand hier etwas Klarheit teilen?

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>


Ich habe einen Satz gehört:

Verschlussgröße wird jedes Mal definiert, dass Funktion läuft

aber immer noch, i'ts nebligen .

+3

Ich lief nur beide und sah keine großen Unterschiede. Haben Sie die Seite vor dem zweiten Test aktualisiert? Wenn nicht, hätten Sie die Größe von "a1" und "a2" (weil sie das gleiche Array sind) auf eine Größe von ungefähr 2000000 erhöht, was die Ursache für die Diskrepanz sein könnte. –

Antwort

12

Ich habe versucht, die Messungen zu starten und zuerst habe ich festgestellt, dass es schwer zu verstehen ist, was passiert, nur mit dem Code aus Ihrer Frage.

Wenn ich diese Tests nacheinander durchführe (Klicken auf die Schaltflächen und Blick auf die Zeitleiste), dann unterscheiden sich die Ergebnisse für jeden nächsten Lauf sehr. Von einigen Läufen sah es aus wie der dritte (run_local_fn) ist in der Regel länger als andere.

Dann habe ich versucht, sie in der umgekehrten Reihenfolge (klicken Sie auf Schaltflächen von 4 bis 1) und bekam das völlig andere Ergebnis - die run_local_obj war die längste.

Also habe ich den Testcode etwas modifiziert, um stabile Ergebnisse zu bekommen.

Voller Code is here, können Sie das Repo klonen und lokal testen.

Hier ist, wie ich jeden Test in Chrome laufen (Ich startete es python -m SimpleHTTPServer 8082 innerhalb des js-perf-test Ordner verwenden):

  • Öffnen Sie die Registerkarte mit http://localhost:8082/perf.html, offene Entwickler-Tools
  • Starten Sie den Zeitplan der Aufnahme
  • Klicken Sie auf die Schaltfläche
  • Warten Sie auf Ergebnisse in der Konsole (min/max/Mittelwert)
  • Stoppen Sie die Timeline Aufnahme

Ergebnisse sind stabil und reproduzierbar (beide Timings und Timeline-Ansicht), hier ist einer der Tests:

Also, was tun wir hier sehen, ist:

1) Die run_proto_obj die schnellste und run_local_obj ist es in der Nähe.

Ich denke, dass es für run_proto_obj am effizientesten sein wird, da es statisch definierte Objekt mit Zeichenfolgen verwendet. Und JS-Engine ist wahrscheinlich in der Lage, die run_local_obj zu optimieren, so das x Objekt wird wiederverwendet und nicht jedes Mal erstellt.

2) Die run_local_fn ist die langsamste. Hier

wir haben das lokale x Objekt und dynamische Strings Berechnung, mehr floating Teile als in anderen Tests.

3) Die run_proto_fn ist schneller als run_local_fn, aber langsamer als die ersten beiden Funktionen.

Ich denke, dies auch zu erwarten ist, wird das Objekt mit a, b, c nur einmal definiert (so ist es schneller als run_local_fn).

Und im Vergleich zu den ersten beiden Funktionen berechnet es die resultierenden Zeichenfolgen dynamisch, also ist es langsamer.

auf Ihre Frage Also zurück:

Wie erwartet run_proto_fn einige Male schneller und mit minimaler Garbage Collection laufen und Low-Memory-Heap. Aber run_proto_obj passierte genau das Gegenteil, als ob es teuer wäre, Nicht-Funktionswerte bei Objektprototypen Eigenschaften zu haben.

Es sieht für mich aus, als ob Sie das Experiment nicht richtig eingerichtet haben. Nach den obigen Ergebnissen ist run_proto_obj tatsächlich die schnellste.

Update: Ich habe gerade versucht, den gleichen Test in Firefox, sind die Ergebnisse ähnlich:

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

die run_proto_obj die schnellste und run_local_fn ist die langsame Europäische Sommerzeit.