简体   繁体   English

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

[英]Is there a performance difference between 'let' and 'var' in JavaScript

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

After testing this on http://jsperf.com , I got the following results:http://jsperf.com上测试后,我得到了以下结果: jsperf has been down for a while; jsperf 宕机有一段时间了; see the replacing code below.请参阅下面的替换代码。

To check this, I'll use the following performance test based on this answer , which led me to write this function:为了检查这一点,我将根据这个答案使用以下性能测试,这促使我编写了这个函数:

 /** * 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>

After testing this in Chrome and Firefox, this shows that let is faster than var , but only when inside a different scope than the main scope of a function.在 Chrome 和 Firefox 中对此进行测试后,这表明letvar快,但仅限于与函数的主作用域不同的作用域内。 In the main scope, var and let are roughly identical in performance.在主作用域中, varlet的性能大致相同。 In IE11 and MS Edge, let and var are roughly equal in performance in both cases.在 IE11 和 MS Edge 中, letvar在两种情况下的性能大致相同。

Press the big blue button to see for yourself in your favourite browser.按下蓝色大按钮,在您喜欢的浏览器中亲自查看。

Currently let has support from only newer browsers , but older browsers are still being used relatively much, which would be a reason to generally not use it yet.目前let只支持较新的浏览器,但较旧的浏览器仍然使用较多,这将是一般尚未使用它的原因。 If you want to use it somewhere where older browsers wouldn't function otherwise, there should be no problem with it.如果您想在旧浏览器无法正常运行的地方使用它,那么它应该没有问题。

Edit: revamped answer since jsperf is not working (see revision history for old version).编辑:修改后的答案,因为 jsperf 不起作用(请参阅旧版本的修订历史记录)。

FYI;供参考; After Chrome v60, no further regressions have cropped up.在 Chrome v60 之后,没有出现进一步的回归。 var and let are neck and neck, with var only ever winning by less than 1%. varlet并驾齐驱, var只赢不到 1%。 Real world scenarios sometimes give var an advantage due to hoisting and re-use, but at that point you're comparing apples to oranges, as let is intended to allow you to avoid that behavior because the semantics are different.由于提升和重用,现实世界的场景有时会给var带来优势,但此时您正在将苹果与橙子进行比较,因为let旨在让您避免这种行为,因为语义不同。

Benchmark . 基准 Firefox, IE and Edge like let just fine.火狐,IE和边缘像let就好了。

Inside loops let is significantly slower see: https://jsperf.com/let-vs-var-loop内部循环明显变慢,请参阅: https : //jsperf.com/let-vs-var-loop

838,602 ±0.77% 61% slower 838,602 ±0.77% 慢 61%

(function() {

  "use strict";
  var a=0;
  for(let i=0;i<100;i++) {
    a+=i;
  }
})();

vs.对比

2,136,387 ±1.09% fastest 2,136,387 ±1.09% 最快

(function() {

  "use strict";
  var a=0;
  for(var i=0;i<100;i++) {
    a+=i;
  }
})();

This is because when using let , for every loop iteration the variable is scoped.这是因为在使用let 时,对于每次循环迭代,变量都是有作用域的。 example:例子:

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

yields to屈服于

0,1,2,3,4,5,6,7,8,9

using var yields to使用 var 产生

10,10,10,10,10,10,10,10,10,10

If you want to have the same result, but using var you have to use an IIFE:如果您想获得相同的结果,但使用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);
}

which on the other hand is significantly slower than using let .另一方面,这比使用let慢得多。

$ 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's LET
     for (let i = 0; i < 1000; i++) {
       sum += i;
       if (sum > 1000000) { sum = 0; }
     }
     return sum;
   })
12144
> timeit(1000000, () => {
     var sum = 0;  // <-- here's VAR
     for (let i = 0; i < 1000; i++) {
       sum += i;
       if (sum > 1000000) { sum = 0; }
     }
     return sum;
   })
2459

Same scope (function), same code, 5 times difference.相同的范围(功能),相同的代码,5 倍的差异。 Similar results in chrome 49.0.2623.75. chrome 49.0.2623.75 中的结果类似。

var : Declare a variable, value initialization optional. var : 声明一个变量,值初始化可选。 Let is faster in outside scope.让在外部范围更快。

let : Declare a local variable with block scope. let :声明一个具有块作用域的局部变量。 Let is a little bit slow in inside loop.让内部循环有点慢。

Ex:前任:

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);

//remade dchekmarev's functions, here are my results: //重新制作dchekmarev的功能,这是我的结果:

//windows 10 x64 (version 1909), XAMPP, Firefox 84.0.2 //windows 10 x64(版本 1909)、XAMPP、Firefox 84.0.2

// in miliseconds: // 以毫秒为单位:

  • var: let:变量:让:
  • 1622 1614 1622 1614
  • 1628 1653 1628 1653
  • 1872 1859 1872 1859
  • 1594 1631 1594 1631
  • 1614 1733 1614 1733
  • 1661 1918 1661 1918
  • 1606 1584 1606 1584
  • 1698 1644 1698 1644
  • 1648 1903 1648 1903
  • 1602 1743 1602 1743

//results are ambiguous, but in most cases var seems a little bit faster //结果不明确,但在大多数情况下, var似乎更快一点

function varTime(times)
{
    var start = (new Date()).getTime();
    var sum = 0; 
     for (var i = 0; i < times; i++) {
        for (var j = 0; j < 1000; j++) {
            sum += j;
            if (sum > 1000000) { sum = 0; }
        }
     };
     console.log('var:', (new Date()).getTime() - start, ' ms');
     return sum;
}

function letTime(times)
{
    let start = (new Date()).getTime();
    let sum = 0; 
     for (let i = 0; i < times; i++) {
        for (let j = 0; j < 1000; j++) {
            sum += j;
            if (sum > 1000000) { sum = 0; }
        }
     };
     console.log('let:', (new Date()).getTime() - start, ' ms');
     return sum;
}

const times = 1000000;

const bla1 = letTime(times);
const bla2 = varTime(times);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM