for-loop中的javascript'let'和'var' [英] javascript 'let' and 'var' in for-loops

查看:255
本文介绍了for-loop中的javascript'let'和'var'的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我搜索具体数字以回溯JavaScript中使用 const 关键字时,我偶然发现所有三种变量声明类型var,let和const之间的性能比较。我不喜欢测试设置,所以我创建了



但是在Chromium中发生了一些奇怪的事情:





不仅所有测试结果都显着降低,而且在循环中断低于一小部分速度。



我决定在Browserstack中运行测试,以确保它不是我古怪的Linux设置。在Windows 10上也有同样的情况发生在 Firefox 53 Chrome 58 。我甚至测试了一些较旧的 Chrome 50 并得到相同的行为。



发生了什么?是否是一个错误?



编辑:有人评论说,循环可能只是被优化了,因为它什么都不做。要表明,情况并非如此,我更改了测试

解决方案

当您使用 let for循环的正文必须创建一个新的范围来处理循环变量的正确生命周期,但是在许多情况下,可以优化掉额外的代码和运行时。例如考虑这个代码:

  let sum = 0; 
let fns = [];
for(let i = 0; i <1000; i ++){
function foo(){sum + = i; }

fns.push(foo);

}

当您通过babeljs运行它时,您可以看到等效的ES5代码生成包括一个函数调用,以保持正确的变量生命周期:

  var sum = 0; 
var fns = [];

var _loop = function _loop(i){
function foo(){
sum + = i;
}

fns.push(foo);
}; (var i = 0; i <1000; i ++){
_loop(i);


}

然而,宝贝很聪明,如果你不做任何需要的事情延长循环变量的使用寿命,它简单地使用一个普通的来获取循环与内部的内联。所以你的代码:

  for(let i = 0; i< 1000; i ++){
true;
}

可以显示为完全相当于:

$ b $ (var i = 0; i <1000; i ++){
true; b

  
}

我的猜测是Chrome内部非常相似,但他们避风港没有优化的情况下,他们不必保持循环变量的生存。



看看我在这个例子在Firefox和Chrome中进行了比较,因为我怀疑他们应该两者都同样缓慢。你应该注意时空,比如空循环,因为结果可能会比实际代码的正常情况要好得多。


On my search for concrete numbers to back usage of the const keyword in Javascript, I stumbled upon a performance comparision between all three variable declaration types var, let and const. I didn't like the test setup, so I created a simplified one.

I didn't expect much difference and Firefox measured up to my expectations:

But in Chromium something weird happened:

Not only are all test results significantly lower but let inside the loop breaks down to a fraction of the speed.

I decided to run the tests in Browserstack to make sure it is not my quirky Linux setup. The same happens there with Firefox 53 and Chrome 58 on Windows 10. I even tested the somewhat older Chrome 50 and got the same behaviour.

What is going on? Is it a bug?

EDIT: Some commented that the loop is probably just optimized away as it is doing nothing. To show, that this is not the case, I changed the test.

解决方案

When you use let the body of the for loop must create a new scope to handle the correct lifetime for the loop variable, however in many cases it is possible to optimise away the extra code and runtime. For example consider this code:

let sum = 0;
let fns = [];
for (let i=0; i < 1000; i++) {
  function foo() { sum += i; }

  fns.push(foo);

}

When you run it through babeljs you can see the equivalent ES5 code it produces includes a function call in order to preserve the correct variable lifetimes:

var sum = 0;
var fns = [];

var _loop = function _loop(i) {
  function foo() {
    sum += i;
  }

  fns.push(foo);
};

for (var i = 0; i < 1000; i++) {
  _loop(i);
}

However, babel is intelligent enough that if you don't do anything which requires extending the lifetime of the loop variable it simply uses an ordinary for loop with the body inline. So your code:

for (let i=0; i < 1000; i++) {
  true;
}

can be shown to be exactly equivalent to:

for (var i=0; i < 1000; i++) {
  true;
}

My guess would be that something very similar happens internally in Chrome, but they haven't yet optimised out the cases where they don't have to keep the loop variable alive.

It would be interesting to see how the code I used at the top of this example compares in Firefox and Chrome as I suspect they should both end up similarly slow. You should beware of timing things like empty loops as the results can be skewed by optimisation far more than is normal for actual code.

这篇关于for-loop中的javascript'let'和'var'的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆