JavaScript临时死区NodeJS 7.9.0性能下降?

我在其他问题中注意到使用letvarvariables声明时循环中的性能差异。

最初的问题是正确的回答,使用let for循环比较慢,因为let为每个迭代创build一个新的范围来保存let声明variables的值。 更多的工作要做,所以慢一点是正常的。 就像参考一样,我给出了代码和NodeJS(7.9.0)执行时间的结果:

请注意下面的所有javascript代码都是关于NodeJS版本7.9.0的

常规代码:

 'use strict'; console.time('var'); for (var i = 0; i < 100000000; i++) {} console.timeEnd('var'); console.time('let'); for (let j = 0; j < 100000000; j++) {} console.timeEnd('let'); 

输出:

 var: 55.792ms let: 247.123ms 

为了避免在循环的每次迭代中对j额外的范围声明,我们在循环之前声明jvariables。 人们会期望,现在应该let循环的性能匹配variables之一。 但不是!!! 这是代码和结果供参考:

在循环之前使用let定义的代码:

 'use strict'; console.time('var'); for (var i = 0; i < 100000000; i++) {} console.timeEnd('var'); console.time('let'); let j; for (j = 0; j < 100000000; j++) {} console.timeEnd('let'); 

输出:

 var: 231.249ms let: 233.485ms 

我们可以看到,不仅let循环没有得到任何更快的速度,而且var循环变得和let循环一样慢! 唯一的解释是,由于我们不在任何块或函数中,所以这两个variables都在全局模块范围内声明。 然而,正如这里所引用的那样,在范围中间的variables的let声明创build了一个暂时的死区 ,它使得variablesj初始化,而var则按照定义初始化variables。

因此,在未经初始化的variables未被引用的情况下,在时间死区运行代码必须相当慢。

最后为了表示尊重,我们在程序的顶部声明了jvariables,以显示运行它的结果,没有时间死区

没有时间死区的代码:

 'use strict'; let j; console.time('var'); for (var i = 0; i < 100000000; i++) {} console.timeEnd('var'); console.time('let'); for (j = 0; j < 100000000; j++) {} console.timeEnd('let'); 

输出:

 var: 55.586ms let: 55.009ms 

现在letvar循环都有类似的优化性能!

有没有人知道我对于时间死区性能的假设是否正确,或提供不同的解释?

这是几个Node版本的testing输出:

 node-v4.0.0 var: 92ms let: 336ms var: 220ms let: 230ms ===== node-v4.2.2 var: 95ms let: 342ms var: 228ms let: 233ms ===== node-v5.1.0 var: 93.418ms let: 342.050ms var: 264.895ms let: 228.310ms ===== node-v5.12.0 var: 103.254ms let: 340.990ms var: 228.698ms let: 228.213ms ===== node-v6.3.1 var: 109.476ms let: 338.127ms var: 232.381ms let: 241.795ms ===== node-v6.5.0 var: 96.630ms let: 339.570ms var: 686.631ms let: 612.820ms ===== node-v6.7.0 var: 106.760ms let: 349.677ms var: 690.753ms let: 587.444ms ===== node-v7.0.0 var: 95.366ms let: 333.880ms var: 222.668ms let: 234.101ms ===== node-v7.4.0 var: 101.074ms let: 330.778ms var: 221.869ms let: 238.053ms ===== node-v7.8.0 var: 93.604ms let: 338.447ms var: 224.263ms let: 233.313ms ===== node-v7.9.0 var: 92.622ms let: 333.552ms var: 275.980ms let: 230.990ms 

这些并不是所有的Node版本,只是我在本地安装的版本,所以很容易testing。

显然这个行为在大多数版本中都是一致的:放在循环之外让它稍微快一些,但是使得var其他地方慢得多。

似乎6.5.0中发生了一些不好的事情,但它是固定的7.x。

它可以留下一些优化的地方,但我不会太担心var越来越慢。 我会更快地let更感兴趣。

让这些例子变成函数并让它们运行几次可以使JIT启动并优化函数,因此结果可能会与第一次运行时看到的结果不同。