为什么在for循环之后使用let比在for循环之前要慢得多?

6

在Node.js v6.0.0版本中

function testlet() {
 let a = 0;
 for (var i = 0; i < 100000000; i++) {}
}

function testlet2() {
 for (var i = 0; i < 100000000; i++) {}
 let a = 0;
}

console.time('let');
testlet();
console.timeEnd('let'); 

console.time('let2');
testlet2();
console.timeEnd('let2'); 

< p>在代码中,let的位置如何导致如此大的性能差异?


在Chrome浏览器中具有相同的效果(没有惊喜),但在其他浏览器中没有这样的区别。 - Jaromanda X
const也会出现这种情况,但对于var,它们的速度是相同的。 - 4castle
2
虽然很奇怪,但我建议不要过于担心。微观优化是一个不断变化的目标。今天快的东西明天很容易变慢。 - Alexander O'Mara
1
在测试中:Node.js和Chrome浏览器显示不同的性能,Firefox与V8相同且更快。Safari不支持let。 - pingfengafei
你能否请发布一下你得到的结果? - Bergi
1个回答

7
我猜测时间死区是罪魁祸首。
那个循环,似乎是你的微基准测试所涉及的内容,正如Vyacheslav Egorov在他的演讲中所说,它被优化器吃掉了早餐。即使不是这样,引擎也会在两个函数中同时增加一个变量一百万次,所需的时间相同。他喜欢这么说

不同之处在于变量 a 的创建时间。在第一个片段中,它位于函数的开头,在它之前没有任何内容。没有暂时性死区,它本质上是函数作用域变量;将其更改为var并不会有任何影响(试一试)。因此,当调用函数时,创建具有变量的作用域,并将值初始化为0,然后运行一些代码(或不运行)。

相反,在第二个片段中存在暂时性死区。在let声明之前的代码中,访问a必须引发异常。因此,当调用函数时,创建作用域并保留a的空间但未初始化。在此状态下,运行代码(或不运行),仅在此之后变量将被初始化并赋值为0

因此,如果let在代码中央(或之后),则作用域更加复杂。这可能会导致优化器以不同的方式处理它,甚至可能影响在同一作用域中的变量i,或者可能无法执行某些优化。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接