Javascript var vs let (de) оптимизация/замедление в v8 и SpiderMonkey
Во время рефакторинга кода JavaScript в моем проекте я обнаружил, что некоторые из моих циклов резко замедлились. Поиск основной причины, я нашел этот вопрос SO, заявляющий о замедлении, вызван оператором 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
})();
Ответы
Ответ 1
Я могу ответить на вопрос V8. Замедление, о котором вы видите, связано с ограничением в старом оптимизирующем компиляторе (известном как "Коленчатый вал" ). Он не был рассмотрен за все это время, потому что команда была занята работой над новым оптимизирующим компилятором ( "Turbofan" ), который поставляется в Chrome 59 (в настоящее время на каналах Canary и Dev, вскоре на Beta!).
В Chrome 58 (в настоящее время на бета-версии) вы уже можете получить предварительный просмотр, установив "Экспериментальный сборник JavaScript для компиляции" на "Включено" (в chrome://flags/#enable-v8-future
). Обратите внимание, что Chrome 59 будет иметь несколько дополнительных улучшений производительности.
Боковое примечание: в существующей кодовой базе нет большой выгоды при переносе на let
, поэтому вы можете просто использовать var
.