Während JavaScript-Code Refactoring in meinem Projekt habe ich festgestellt, dass einige meiner Schleifen drastisch verlangsamt. Suche nach der Ursache habe ich this SO question gefunden, die Verlangsamung wird durch let
Anweisung innerhalb for
Schleife und Verschluss Schaffung verursacht. Zu meiner Überraschung let
und Verschluss aus der for
Schleife bewegt hat nicht geholfen, und mit sogar var
statt let
für Schleifenvariable hilft nicht, auch weil Verlangsamung durch let
verursacht wird nach die for
Schleife gelegt. Durch zusätzliche Details zu entfernen Ich habe diesen Code-Schnipsel erhalten:Javascript var vs lassen (de) Optimierung/Verlangsamung Problem in v8 und SpiderMonkey
"use strict"
console.log("=========================");
(function(){
var itr = 0;
function f(){++itr;}
console.time('without_let');
for(var i = 0; i < 50000000; ++i){
f();
}
var totals = 0;
console.timeEnd('without_let'); //chrome: 122ms, FF:102ms
})();
(function(){
var itr = 0;
function f(){++itr;}
console.time('let_below');
for(var i = 0; i < 50000000; ++i){
f();
}
let totals = 0; // <--- notice let instead of var
console.timeEnd('let_below'); //chrome: 411ms, FF:99ms
})();
(function(){
let itr = 0;
function f(){++itr;}
console.time('let_above_and_in_loop');
for(let i = 0; i < 50000000; ++i){
f();
}
var totals = 0;
console.timeEnd('let_above_and_in_loop'); //chrome: 153ms, FF:899ms
})();
(function(){
var itr = 0;
function f(){++itr;}
console.time('let_in_loop');
for(let i = 0; i < 50000000; ++i){
f();
}
var totals = 0;
\t \t console.timeEnd('let_in_loop'); //chrome: 137ms, FF:102ms
})();
(auch auf JS Fiddle Hinweis: Verwendung von JS Fiddle zeigt wenig unterschiedliche Ergebnisse, aber ähnliche Verlangsamung ist noch in den gleichen Orten)
Ausführen dieses auf Chrome produziert folgende
without_let: 122ms
let_below: 411ms <----------- Slowdown for v8
let_above_and_in_loop: 153ms
let_in_loop: 137ms
Irgendein Googeln brachte mich zu the article, das besagt, dass let
vor Chrome 56/V8 5.6 eine Deoptimisierung verursachte! aber mein Chrom ist 57.0.2987.133 (64-bit) und v8 ver 5.7.492.71. Weitere Überraschungen versuchen, dies auf Firefox 52.0.2 (32-Bit) zu starten. Hier haben wir Verlangsamung an einem anderen Ort, wenn Variable erstellt mit let
innen Verschluss verwendet wird:
without_let: 101.9ms
let_below: 99ms
let_above_and_in_loop: 899ms <----- Slowdown for SpiderMonkey
let_in_loop: 102ms
Wie ich sehe das Problem ist etwas im Zusammenhang mit so „Temporal Dead Zone“ -Funktion genannt, aber immer noch unklar:
Warum können zwei Hauptbrowser (Haupt-JavaScript-Engines) diese (verschiedenen) Teile des Snippets immer noch nicht optimieren?
Gibt es Workarounds zur Verwendung
let
(außer mit Babel in var zu drehen lassen)? Angenommen, ich bin in der Lage Optionen Chrome passieren oder auch direkt an v8 überv8::V8::SetFlagsFromCommandLine(&argc, argv, true);
UPD: In Chrome ver 58.0.3029.96, v8 Version 5.8.283.37 correspondng (aconding zu https://omahaproxy.appspot.com/) nach Chrom ermöglicht : // flags/# enable-v8-Zukunft als jmrk unten vorgeschlagen noch Verlangsamung für den dritten Fall (jetzt 2 mal statt 8 mal)
without_let: 157.000ms
let_below: 155.000ms
let_above_and_in_loop: 304.000ms
let_in_loop: 201.000ms
Firefox 53.0 (32bit)
ist
Es ist nicht so, dass sie * nicht * können, sondern dass sie noch nicht die Zeit gefunden haben, es zu implementieren. Vielleicht möchten Sie einige Fehlerberichte einreichen, um diese zu priorisieren. – Bergi
Hier ist Bericht für v8 https://bugs.chromium.org/p/v8/issues/detail?id=6188 und hier für FF https://support.mozilla.org/en-US/questions/1158956 –
Hier ist auch Bugzilla Artikel https://bugzilla.mozilla.org/show_bug.cgi?id=1362930 –