2016-09-21 114 views
6

在node.js的V6.0.0为什么在for循环之后比for循环之前慢得多?

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

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

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

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

如何在代码let位置引起如此大的性能差异?

+0

在chrome中的效果相同(没有惊喜) - 在其他浏览器中没有这样的差异 –

+0

它也发生在'const'上,但是'var'对于两者来说都是相同的速度。 – 4castle

+2

奇怪的是,我建议不要担心太多。微优化是一个移动的目标。今天速度很快,明天可能会很慢。测试下的 –

回答

7

我会采取一个有教养的猜测,并说temporal dead zone是罪魁祸首。

在他的演讲中,该循环似乎是您的微基准所关注的内容,即eaten by the optimiser for breakfast作为Vyacheslav Egorov likes to put it。即使不是这样,引擎会增加一百万次变量,但这两种功能都需要相同的时间。

有什么不同是当变量a创建。在你的第一个片段中,它在函数的开头,没有任何东西在它之前。没有时间死区,它本质上是一个函数范围变量;将它改为var不会有什么区别(尝试它)。因此,当函数被调用时,带有变量的作用域被创建并且该值被初始化为0,然后一些代码运行(或不运行)。
相比之下,在第二个片段中有一个时间死区。在声明let之前的代码中,访问a必须抛出异常。所以当函数被调用时,范围被创建,a的一个插槽被保留,但保持未初始化。在这种状态下,代码运行(或不运行),只有在该变量将被初始化并赋值0

因此,如果let处于代码之中(或之后),范围更加复杂。这可能会导致优化器以不同的方式对待它,甚至可能影响处于相同范围内的变量i,或者可能根本无法执行某些优化。