Почему допустимо медленнее, чем var в цикле for в nodejs?
Я написал очень простой тест:
console.time('var');
for (var i = 0; i < 100000000; i++) {}
console.timeEnd('var')
console.time('let');
for (let i = 0; i < 100000000; i++) {}
console.timeEnd('let')
Если вы используете Chrome, вы можете попробовать его здесь (поскольку NodeJS и Chrome используют один и тот же движок JavaScript, хотя обычно немного разные версии):
// Since Node runs code in a function wrapper with a different
// `this` than global code, do that:
(function() {
console.time('var');
for (var i = 0; i < 100000000; i++) {}
console.timeEnd('var')
console.time('let');
for (let i = 0; i < 100000000; i++) {}
console.timeEnd('let')
}).call({});
Ответы
Ответ 1
Основываясь на различии между механикой var
и let
, это связано с тем, что var
существует во всей области блока анонимной функции, тогда как let
существует только внутри цикла и должен быть повторно объявленным для каждой итерации. 1 Вот пример, демонстрирующий эту точку:
(function() {
for (var i = 0; i < 5; i++) {
setTimeout(function() {
console.log(`i: ${i} seconds`);
}, i * 1000);
}
// 5, 5, 5, 5, 5
for (let j = 0; j < 5; j++) {
setTimeout(function() {
console.log(`j: ${j} seconds`);
}, 5000 + j * 1000);
}
// 0, 1, 2, 3, 4
}());
Ответ 2
По этому вопросу. Я пытаюсь найти некоторый ключ формы хром V8 исходный код. вот код пилинга пика V8:
https://github.com/v8/v8/blob/5.4.156/src/compiler/loop-peeling.cc
Я пытаюсь это понять, я считаю, что для цикла имеет средний уровень в реализации. для цикла будет удерживать значение приращения в среднем слое.
Если использование цикла позволяет объявить "i" , V8 объявит новую переменную я для каждой итерации цикла, скопирует значение переменной приращения среднего уровня на эту новую объявленную "i" , а затем поместит ее в область тела цикла;
Если цикл использует var для объявления "i" , V8 будет только ссылаться на значение среднего значения среднего уровня для области тела цикла. Это уменьшит накладные расходы на производительность итерации цикла.
Извините за мой английский. В исходном коде v8 есть график, который покажет вам механизм.