我注意到其他question循环中的性能差异,同时使用let
和var
变量声明。Javascript临时死区NodeJS 7.9.0性能下降?
初始问题是正确地回答的是,在使用let
for循环较慢因为let
创建用于每次迭代保持let
声明的变量的值的新范围。要做更多的工作,所以慢一些是正常的。正如参考,我给的代码和的NodeJS(7.9.0)的执行时间的结果:
请注意,以下关于版本的NodeJS所有的JavaScript代码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
,我们在循环之前声明j
变量。可以预料,现在这应该使let
循环性能匹配var
之一。 但是没有!这是代码,结果以供参考:循环之前定义
代码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
一样慢!唯一的解释是,由于我们不在任何块或函数中,因此这两个变量都在全局模块范围内声明。然而,如here所示,范围中间的变量的let
声明创建了时间死区,这使j
变量未初始化,而var
初始化如定义的变量。
所以虽然未初始化的变量没有被引用的时间死区运行的代码,必须相当慢....
最后以显示尊重,我们声明的程序顶部的j
变量显示运行它的结果没有暂时死区。
代码不具有时间盲区:
'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
现在无论let
和var
循环也有类似的性能优化!
有没有人知道我对假死区性能的假设是否正确,或提供不同的解释?
有趣的问题 - upvoted,你也应该在其他环境中尝试。 –
我也很好奇那个,可能是关于内存分配的东西 –
这与TDZ绝对有关。请参阅[“性能”项目的要点](http://jsrocks.org/2015/01/temporal-dead-zone-tdz-demystified#tdz-is-everywhere-except-in-transpilers-and-engines)。这在我的脑海中是有道理的,但对我来说写一个答案还不够好。 –