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.