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

时间:2016-09-21 03:12:27

标签: javascript node.js let

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

代码中let的位置如何导致如此大的性能差异?

1 个答案:

答案 0 :(得分:7)

我会采取有根据的猜测,并说temporal dead zone是罪魁祸首。

这个循环似乎是你的微基准所关注的,正如Vyacheslav Egorov eaten by the optimiser for breakfast在他的谈话中likes to put it。即使它不是,并且引擎会将变量增加一百万次,在两个函数中都需要相同的时间。

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

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