Есть ли разница в производительности между 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);