Есть ли разница в производительности между let и var в JavaScript
Разница между этими двумя ключевыми словами с точки зрения охвата уже была подробно обсуждена здесь , но мне было интересно, есть ли разница в производительности между этими двумя, и если да, то это незначительно или в какой момент это станет значительным?
Ответы
Ответ 1
После тестирования этого параметра на http://jsperf.com, я получил следующие результаты: jsperf на некоторое время; см. заменяющий код ниже.
Чтобы проверить это, я буду использовать следующий тест производительности на основе этого ответа, который заставил меня написать эту функцию:
/**
* Finds the performance for a given function
* function fn the function to be executed
* int n the amount of times to repeat
* return array [time for n iterations, average execution frequency (executions per second)]
*/
function getPerf(fn, n) {
var t0, t1;
t0 = performance.now();
for (var i = 0; i < n; i++) {
fn(i)
}
t1 = performance.now();
return [parseFloat((t1 - t0).toFixed(3)), parseFloat((repeat * 1000 / (t1 - t0)).toFixed(3))];
}
var repeat = 100000000;
var msg = '';
//-------inside a scope------------
var letperf1 = getPerf(function(i) {
if (true) {
let a = i;
}
}, repeat);
msg += '<code>let</code> inside an if() takes ' + letperf1[0] + ' ms for ' + repeat + ' iterations (' + letperf1[1] + ' per sec).<br>'
var varperf1 = getPerf(function(i) {
if (true) {
var a = i;
}
}, repeat);
msg += '<code>var</code> inside an if() takes ' + varperf1[0] + ' ms for ' + repeat + ' iterations (' + varperf1[1] + ' per sec).<br>'
//-------outside a scope-----------
var letperf2 = getPerf(function(i) {
if (true) {}
let a = i;
}, repeat);
msg += '<code>let</code> outside an if() takes ' + letperf2[0] + ' ms for ' + repeat + ' iterations (' + letperf2[1] + ' per sec).<br>'
var varperf2 = getPerf(function(i) {
if (true) {}
var a = i;
}, repeat);
msg += '<code>var</code> outside an if() takes ' + varperf1[0] + ' ms for ' + repeat + ' iterations (' + varperf1[1] + ' per sec).<br>'
document.getElementById('out').innerHTML = msg
<output id="out" style="font-family: monospace;white-space: pre-wrap;"></output>
Ответ 2
FYI; После Chrome v60 дальнейших регрессий не возникло. var
и let
- это шея и шея, причем var
только выигрывает менее чем на 1%. Сценарии реального мира иногда дают var
преимущество из-за подъема и повторного использования, но в этот момент вы сравниваете яблоки с апельсинами, так как let
позволяет вам избежать такого поведения, потому что семантика отличается.
Контрольный показатель. Firefox, IE и края, как let
просто отлично.
Ответ 3
Внутренние циклы Пусть значительно медленнее:
https://jsperf.com/let-vs-var-loop
838602
± 0,77%
61% медленнее
(function() {
"use strict";
var a=0;
for(let i=0;i<100;i++) {
a+=i;
}
})();
против.
2136387
± 1,09%
быстрый
(function() {
"use strict";
var a=0;
for(var i=0;i<100;i++) {
a+=i;
}
})();
Это связано с тем, что при использовании let для каждой итерации цикла переменная имеет область действия. Пример:
for (let i = 0; i < 10 ; i++) {
setTimeout(function() { console.log(i); }, 100 * i);
}
дает
0,1,2,3,4,5,6,7,8,9
с использованием var дает значение
10,10,10,10,10,10,10,10,10,10
Если вы хотите иметь тот же результат, но используя var, вам нужно использовать IIFE:
for (var i = 0; i < 10; i++) {
// capture the current state of 'i'
// by invoking a function with its current value
(function(i) {
setTimeout(function() { console.log(i); }, 100 * i);
})(i);
}
который, с другой стороны, значительно медленнее, чем использование let.
Ответ 4
$ node --version
v6.0.0
$ node
> timeit = (times, func) => {
let start = (new Date()).getTime();
for (let i = 0; i < times; i++) {
func();
};
return (new Date()).getTime() - start;
};
[Function]
> timeit(1000000, () => {
let sum = 0; // <-- here LET
for (let i = 0; i < 1000; i++) {
sum += i;
if (sum > 1000000) { sum = 0; }
}
return sum;
})
12144
> timeit(1000000, () => {
var sum = 0; // <-- here VAR
for (let i = 0; i < 1000; i++) {
sum += i;
if (sum > 1000000) { sum = 0; }
}
return sum;
})
2459
То же пространство (функция), тот же код, разница в 5 раз. Аналогичные результаты в хроме 49.0.2623.75.
Ответ 5
var: объявить переменную, инициализация значения необязательна. Пусть скорее вне области.
let: объявить локальную переменную с областью действия блока. Пусть немного медленнее во внутреннем цикле.
Пример:
var a;
a = 1;
a = 2; //re-intilize possibe
var a = 3; //re-declare
console.log(a); //3
let b;
b = 5;
b = 6; //re-intilize possibe
// let b = 7; //re-declare not possible
console.log(b);