JavaScript中的'let'和'var'之间是否存在性能差异?

Nic*_*lai 50 javascript performance scope

这两个关键字在范围界定方面的差异已经在这里进行了彻底的讨论,但我想知道两者之间是否存在任何性能差异,如果是这样,它是否可以忽略不计,或者在什么时候会变得显着?

Joe*_*e50 53

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
Run Code Online (Sandbox Code Playgroud)
<output id="out" style="font-family: monospace;white-space: pre-wrap;"></output>
Run Code Online (Sandbox Code Playgroud)

在Chrome和Firefox中对此进行测试后,这表明let速度快于var,但仅限于与函数主范围不同的范围内.在主要适用范围,varlet在性能上大致相同.在IE11和MS边缘,let并且var是在这两种情况下的性能大致相等.

按下蓝色大按钮,在您喜欢的浏览器中查看.

目前let已经从只有较新的浏览器的支持,但旧的浏览器仍在使用比较多的,这将是一个理由,一般不使用它.如果你想在旧版浏览器无法正常工作的地方使用它,那么应该没有问题.

编辑:由于jsperf不起作用而修改了答案(请参阅旧版本的修订历史记录).

  • 如果`let`在现实世界中比`var`快,那么这个测试可能不会测试.您不知道浏览器生成的代码类型.代码非常简单,因为结果从未使用过,而ifs是常量chrome,可以很容易地删除所有代码.请参阅[这是针对微小基准测试的例子](http://stackoverflow.com/questions/16156130/why-is-my-program-so-slow/16156167).这是C++,但它的要点仍然相关. (3认同)
  • Chrome浏览器不支持`let`,在Firefox中,您应提供类型属性`&lt;script type =“ application / javascript; version = 1.7”&gt;` (2认同)

Tyl*_*Y86 19

仅供参考; 在Chrome v60之后,没有出现进一步的回归.var并且let是颈部和颈部,var只有不到1%的胜利.var由于提升和重复使用,真实场景有时会带来优势,但此时您正在将苹果与橙子进行比较,因为let这样可以避免这种行为,因为语义不同.

基准.Firefox,IE和Edge就好let了.

  • 只是一个更新; let仍然比Chrome上的var慢,并且在其他地方相等. (5认同)
  • Chrome 52,让我们几乎仍然获胜:让内部范围x 93,575,363 ops/sec±2.28%(58运行采样),var范围内x 81,266,031 ops/sec±1.84%(58运行采样),让外部范围x 90,070,266 ops/sec ±1.37%(采样61次运行),变量超出范围x 82,425,646 ops/sec±1.34%(59次运行采样) (5认同)
  • 从Chrome 55开始,让范围内的胜利增加21%,var在范围外赢得55%.我勒个去. (5认同)
  • 截至60.0.3112.113 var和let具有相同的性能. (3认同)
  • 从Chrome v51.0.2704.84 m(64位)(V8 5.1.281.59)开始,`let`在所有情况下都可能比`var`更快,约为5%,同时不会损失`var`性能,整体而言在同一系统上通常较高的分数. (2认同)

小智 6

内部循环明显变慢,请参阅:https : //jsperf.com/let-vs-var-loop

838,602 ±0.77% 慢 61%

(function() {

  "use strict";
  var a=0;
  for(let i=0;i<100;i++) {
    a+=i;
  }
})();
Run Code Online (Sandbox Code Playgroud)

对比

2,136,387 ±1.09% 最快

(function() {

  "use strict";
  var a=0;
  for(var i=0;i<100;i++) {
    a+=i;
  }
})();
Run Code Online (Sandbox Code Playgroud)

这是因为在使用let 时,对于每次循环迭代,变量都是有作用域的。例子:

for (let i = 0; i < 10 ; i++) {
    setTimeout(function() { console.log(i); }, 100 * i);
}
Run Code Online (Sandbox Code Playgroud)

屈服于

0,1,2,3,4,5,6,7,8,9
Run Code Online (Sandbox Code Playgroud)

使用 var 产生

10,10,10,10,10,10,10,10,10,10
Run Code Online (Sandbox Code Playgroud)

如果您想获得相同的结果,但使用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);
}
Run Code Online (Sandbox Code Playgroud)

另一方面,这比使用let慢得多。

  • 是的,chrome 和 node 慢了 60%,而 FF 没有区别。 (2认同)