在使用let
和var
变量声明时,我注意到其他question循环中的性能差异。
正确回答了最初的问题,即在 for循环中使用let
的速度较慢,因为let
为每次迭代创建一个新的范围,以保存{{1}的值声明的变量。还有更多工作要做,所以慢一点是正常的。作为参考,我在NodeJS(7.9.0)执行时间中给出代码和结果:
请注意,以下所有javascript代码均与NodeJS版本7.9.0相关
常规代码:
let
输出:
'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
循环一样慢!!!对此的唯一解释是,由于我们不在任何块或函数中,因此两个变量都在全局模块范围内声明。但是,在引用here时,范围中间的变量的let
声明会创建一个暂时死区,这会使变量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
循环都有类似的优化效果!
有谁知道我关于暂时死区表现的假设是否正确,或提供不同的解释???
答案 0 :(得分:2)
这是几个版本的Node上测试的输出:
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版本,只是我在本地安装的版本,所以它很容易测试。
显然,大多数版本的行为都是一致的:将let
置于循环之外使其稍微快一点,但它会使var
在其他地方慢得多。
似乎6.5.0中发生了一些不好的事情,但是修复了7.x。
它可以留出一些优化的地方,但我不会太担心var
变慢。我更感兴趣的是让let
更快。
将这些示例放入函数并让它们运行多次可以使JIT启动并优化函数,因此结果可能与您第一次运行所有内容时的结果不同。