【问题标题】:let vs var performance in nodejs and chromelet vs var 在 nodejs 和 chrome 中的性能
【发布时间】:2016-08-06 00:39:12
【问题描述】:

当我在 chrome 和 nodejs 中测试以下代码时,我得到以下结果:

铬:

带有 VAR 的 for 循环:24.058ms
带 LET 的 for 循环:8.402ms

NodeJS:

带有 VAR 的 for 循环:4.329ms
带 LET 的 for 循环:8.727ms

据我了解,由于块作用域 LET 在 chrome 中更快。但是有人可以帮我理解为什么它在 NodeJS 中是相反的吗? 还是我错过了什么?

"use strict";
console.time("for loop with VAR");
for (var i = 0; i < 1000000; i += 1) {
 // Do nothing
}
console.timeEnd("for loop with VAR");

console.time("for loop with LET");
for (let i = 0; i < 1000000; i += 1) {
 // Do nothing
}
console.timeEnd("for loop with LET");` 

PS:不确定这是否不是测试性能的理想方法。

【问题讨论】:

  • 当我颠倒测试的顺序时,第一个(让)更快。比例差不多。
  • 你使用的是什么版本的节点?
  • @maioman 使用 v5.10
  • 此类测试的问题在于(至少在原则上)运行时优化可能会发现代码完全没有副作用,而根本不这样做。让循环真正做一些事情(一些便宜的事情),看看有什么不同。
  • 好吧,我的点是,开销的差异可能完全被代码正在执行的实际工作的成本所掩盖。

标签: javascript node.js performance google-chrome


【解决方案1】:

当你这样做时

for (let i = 0; i < 1000000; i += 1) { }

每个循环周期中的 i 值是一个单独的引用,这在异步回调中使用 i 值时很有用。这速度较慢,但​​在此用例中可能比其他方法更快。

当你使用

let j;
for (j = 0; j < 1000000; ++j) { }

您将只有一个值引用,它与使用 var 一样快。

试试下面的代码

console.time("let i");
for (let i = 0; i < 10000000; ++i) { }
console.timeEnd("let i");
console.time("let j");
let j;
for (j = 0; j < 10000000; ++j) { }
console.timeEnd("let j");
console.time("var k");
for (var k = 0; k < 10000000; ++k) { }
console.timeEnd("var k");

这将给出类似的结果

let i: 91ms
let j: 25ms
var k: 27ms

当正确使用时,显然 let 与 var 一样快。

还要查看异步行为的区别,试试

for (let i = 0; i < 3; ++i) {
    setImmediate(() => { console.log(i) });
}
let j;
for (j = 0; j < 3; ++j) {
    setImmediate(() => { console.log(j) });
}
for (var k = 0; k < 3; ++k) {
    setImmediate(() => { console.log(k) });
}

哪个会输出

0
1
2
3
3
3
3
3
3

在 for let i 循环的每个循环中,i 值都是唯一的引用,这就是导致轻微开销的原因,而对于其他两个循环,它是相同的引用。

【讨论】:

    【解决方案2】:

    V8 版本附带 node.js 5.10 don't supporttemporal dead zone 用于 let 绑定。​​

    Chrome 正在使用支持它的 V8 5.0...但是由于 vm 尚未针对处理 TDZ 进行优化,所以现在它较慢是正常的(我记得读过有人断言用 let 替换 var 使代码关于慢 27%)。

    【讨论】:

      【解决方案3】:

      我无法告诉您更多信息,但正如本视频中提到的(非常好),您需要更智能的代码来测试它。 https://www.youtube.com/watch?v=65-RbBwZQdU 如果你不使用i 并且循环是空的,编译器会magic 用你的代码填充,甚至可能消除循环

      【讨论】:

      • 难道 let 行为正常,但只有 var 看起来很奇怪?因为两个“让”都有相似的结果。
      • 我不知道编译器做了什么,但它可能是因为 let 只为 for 范围创建,但 var 也可以在外部使用
      猜你喜欢
      • 1970-01-01
      • 2021-09-14
      • 2015-06-05
      • 2014-11-16
      • 2018-06-08
      • 1970-01-01
      • 2017-10-28
      • 2014-02-23
      • 1970-01-01
      相关资源
      最近更新 更多