2016-04-14 5 views
6

Als ich in Chrom und NodeJS folgenden Testcode, bekomme ich folgende:lassen vs var Leistung in NodeJS und Chrom

Chrome:

for-Schleife mit VAR: 24.058ms
for-Schleife mit LET: 8.402ms

NodeJS:

for-Schleife mit VAR: 4.329ms
for-Schleife mit LET: 8.727ms

Gemäß meinem Verständnis ist wegen Block Scoping LET schneller in Chrom . Aber kann mir jemand helfen zu verstehen, warum ist es in NodeJS umgekehrt? Oder fehlt mir etwas?

"use strict"; 
console.time("for loop with VAR"); 
for (var i = 0; i < 1000000; i += 1) { 
// Do nothing 
} 
console.timeEnd("for loop with VAR"); 

console.time("for loop with LET"); 
for (let i = 0; i < 1000000; i += 1) { 
// Do nothing 
} 
console.timeEnd("for loop with LET");` 

PS: Nicht sicher, ob dies nicht der ideale Weg ist, die Leistung zu testen.

+0

Wenn ich die Reihenfolge der Tests umdrehte, war der erste (let) schneller. In ungefähr demselben Verhältnis. – ptrk

+0

Welche Version von Knoten verwenden Sie? – maioman

+0

@maioman mit v5.10 – BeingDev

Antwort

6

V8-Version mit node.js ausgeliefert 5.10 don't support der temporal dead zone für Bindungen let .

Chrome verwendet stattdessen V8 5.0, die es unterstützen ... aber da das vm noch nicht für TDZ optimiert ist, ist es normal, dass es jetzt langsamer ist (ich erinnere mich, Leute gelesen zu haben, die behaupten, var durch den Code zu ersetzen etwa 27% langsamer).

-1

ich kann dir nicht mehr sagen, aber wie in diesem Video erwähnt (sehr gut), brauchst du einen intelligenteren Code, um das zu testen. https://www.youtube.com/watch?v=65-RbBwZQdU wird der Compiler Magie Sachen mit Ihrem Code und könnte ereas auch die Schleife, wenn Sie nicht i verwenden und die Schleife ist leer

+0

Könnte es sein, dass sich normal verhält, aber nur var scheint seltsam? Da beide "lassen" ähnliche Ergebnisse haben. – Paran0a

+0

Ich weiß nicht, was der Compiler tut, aber es könnte sein, da let nur für den 'for'-Bereich erstellt wird, aber var könnte auch außerhalb verwendet werden – yellowsir

1

Beim

for (let i = 0; i < 1000000; i += 1) { } 

der I-Wert in jedem Schleifenzyklus tut, ist eine separate Referenz, was nützlich ist, wenn sie in einem asynchronen Rückruf des i-Wert. Dies ist langsamer, kann jedoch in diesem Anwendungsfall schneller als Alternativen sein.

Wenn Sie stattdessen

verwenden
let j; 
for (j = 0; j < 1000000; ++j) { } 

Sie wird nur ein Referenzwert haben, und es wird genauso schnell wie mit var sein.

Versuchen Sie, den folgenden Code

console.time("let i"); 
for (let i = 0; i < 10000000; ++i) { } 
console.timeEnd("let i"); 
console.time("let j"); 
let j; 
for (j = 0; j < 10000000; ++j) { } 
console.timeEnd("let j"); 
console.time("var k"); 
for (var k = 0; k < 10000000; ++k) { } 
console.timeEnd("var k"); 

dies wird Ergebnisse liefern wie

let i: 91ms 
let j: 25ms 
var k: 27ms 

wo deutlich lassen gleich schnell zu var ist, wenn richtig eingesetzt.

auch den Unterschied in asynchronem Verhalten zu sehen, versucht

for (let i = 0; i < 3; ++i) { 
    setImmediate(() => { console.log(i) }); 
} 
let j; 
for (j = 0; j < 3; ++j) { 
    setImmediate(() => { console.log(j) }); 
} 
for (var k = 0; k < 3; ++k) { 
    setImmediate(() => { console.log(k) }); 
} 

die Ausgabe wird

0 
1 
2 
3 
3 
3 
3 
3 
3 

wie in jedem Zyklus der Schleife i Wert des i für Let eine eindeutige Referenz, die ist, was den leichten Overhead verursacht, während es für die anderen beiden Loops die gleiche Referenz ist.