Я протестировал это в Chrome ver 58.0.3029.96 - оптимизация убрала это резкое замедление, но все же третий случай почти в два раза медленнее
емя рефакторинга кода JavaScript в моем проекте я обнаружил, что некоторые из моих циклов резко замедлились. Поиск основной причины, которую я нашелэтот ТАК вопрос Заявление о замедлении вызваноlet
заявление внутриfor
создание цикла и замыкания. К моему удивлению, переездlet
и закрытие изfor
петля не помогла, и даже используяvar
вместоlet
переменная цикла также не помогает, потому что замедление вызваноlet
помещенныйпосле for
петля. Удалив дополнительные детали, я получил этот фрагмент кода:
"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;
console.timeEnd('let_in_loop'); //chrome: 137ms, FF:102ms
})();
(также наJS Fiddle Примечание: использование JS Fiddle показывает немного разные результаты, но аналогичное замедление все еще присутствует в тех же местах)
Запуск этого на Chrome производит следующее
without_let: 122ms
let_below: 411ms <----------- Slowdown for v8
let_above_and_in_loop: 153ms
let_in_loop: 137ms
Некоторый поиск в Google привел меня кстатья основываясь на этомlet
вызвал деоптимизацию до Chrome 56 / V8 5.6! но у меня chrome 57.0.2987.133 (64-битный) и v8 ver 5.7.492.71. Больше сюрпризов при попытке запустить это на Firefox 52.0.2 (32-разрядная версия). Здесь мы имеем замедление в другом месте, когда переменная создана сlet
используется внутри закрытия:
without_let: 101.9ms
let_below: 99ms
let_above_and_in_loop: 899ms <----- Slowdown for SpiderMonkey
let_in_loop: 102ms
Как я вижу, проблема в некоторой степени связана с так называемой функцией «временной мертвой зоны», но все еще неясна:
Почему два основных браузера (основные движки JavaScript) по-прежнему не могут оптимизировать эти (разные) части фрагмента?
Есть ли обходные пути, чтобы продолжать использоватьlet
(Кроме используя Babel, чтобы превратить let в var)? Предположим, я могу передать параметры в Chrome или даже напрямую в V8 черезv8::V8::SetFlagsFromCommandLine(&argc, argv, true);
UPD: В Chrome ver 58.0.3029.96, соответствующая версии 5.8.283.37 v8 (согласноhttps://omahaproxy.appspot.com/) после включения chrome: // flags / # enable-v8-future, как предложено ниже jmrk, в третьем случае все еще наблюдается замедление (теперь 2 раза вместо 8 раз)
without_let: 157.000ms
let_below: 155.000ms
let_above_and_in_loop: 304.000ms
let_in_loop: 201.000ms
Firefox 53.0 (32 бита)
without_let: 278.650ms
let_below: 310.290ms
let_above_and_in_loop: 848.325ms
let_in_loop: 275.495ms