[英]Why does this JavaScript code run slower after Node.js optimization
I was creating a solution to an ICPC problem using JavaScript and Node.js when I ran into an interesting issue: under certain circumstances my program would run twice as slow on the same data set. 当我遇到一个有趣的问题时,我正在使用JavaScript和Node.js创建一个ICPC问题的解决方案:在某些情况下,我的程序在同一数据集上的运行速度会慢两倍。
I stripped it down until I got to this minimal example that demonstrates the behavior: 我把它剥离了,直到我得到这个演示行为的最小例子:
function solve(arr) {
const total = arr.reduce((a, c) => a + c, 0);
const count = arr.length;
for (let i = 0; i < total; i++) {
for (let j = 0; j < count; j++) {
// calculate some stuff
}
}
}
for (let i = 0; i < 10; i++) {
// generate some sample data (array of 5000 random numbers 1-10)
const data = [];
for (let i = 0; i < 5000; i++) {
data.push(Math.floor(Math.random() * 10) + 1);
}
const start = new Date();
solve(data); // run solve on the data
console.log(`${i + 1}: ${new Date() - start}ms`);
}
This is the output of running node --trace-opt code.js
using Node
v10.15.1: 这是使用
Node
v10.15.1运行node --trace-opt code.js
的输出:
[marking 0x005062b82521 <JSFunction solve (sfi = 000001DA56AD8CD9)> for optimized recompilation, reason: small function, ICs with typeinfo: 5/7 (71%), generic ICs: 0/7 (0%)]
[compiling method 0x005062b82521 <JSFunction solve (sfi = 000001DA56AD8CD9)> using TurboFan OSR]
[optimizing 0x005062b82521 <JSFunction solve (sfi = 000001DA56AD8CD9)> - took 1.453, 0.702, 0.082 ms]
1: 86ms
[marking 0x005062b82581 <JSFunction (sfi = 000001DA56AD8BD9)> for optimized recompilation, reason: hot and stable, ICs with typeinfo: 22/23 (95%), generic ICs: 1/23 (4%)]
[compiling method 0x005062b82521 <JSFunction solve (sfi = 000001DA56AD8CD9)> using TurboFan]
[optimizing 0x005062b82521 <JSFunction solve (sfi = 000001DA56AD8CD9)> - took 0.159, 0.632, 0.096 ms]
2: 82ms
3: 80ms
[compiling method 0x005062b82581 <JSFunction (sfi = 000001DA56AD8BD9)> using TurboFan OSR]
[optimizing 0x005062b82581 <JSFunction (sfi = 000001DA56AD8BD9)> - took 0.592, 2.312, 0.154 ms]
4: 245ms
5: 243ms
6: 236ms
7: 237ms
8: 240ms
9: 246ms
10: 239ms
During the first three iterations the run time is around 80ms, but just before the fourth iteration Node
recompiles and optimizes a method and from that point on the code runs about 3 times slower . 在前三次迭代期间,运行时间大约为80ms,但就在第四次迭代之前,
Node
重新编译并优化了一个方法,从那时起代码运行速度慢了大约3倍 。
Typically when Node
does runtime analysis, recompilation, and optimization everything runs faster. 通常,当
Node
执行运行时分析,重新编译和优化时,一切运行得更快。
Can anyone explain why Node
optimization makes things so much worse in this case? 任何人都可以解释为什么
Node
优化在这种情况下使事情变得更糟糕?
Note that if the example code is changed to calculate total
by iterating instead of using reduce
the optimization improves performance as expected (run time drops to around 60ms): 请注意,如果将示例代码更改为通过迭代而不是使用
reduce
来计算total
,则优化会按预期提高性能(运行时间降至约60ms):
let total = 0;
for (let v of arr) total += v;
I filed a bug report and got the following response from a Chromium dev: 我提交了一份错误报告,并从Chromium dev获得以下回复 :
Some array builtins used branch hints for loop bounds checks, causing all code after the inlined builtin to become deferred code.
一些数组内置函数使用分支提示进行循环边界检查,导致内联内置函数之后的所有代码成为延迟代码。 This is detrimental for performance.
这对性能不利。
So it turns out this is a known issue with the TurboFan
compiler and a fix has been created and is currently being tested: 所以事实证明这是
TurboFan
编译器的一个已知问题,并且已经创建了一个修复程序 ,目前正在测试中:
This CL removes the hints, which improves code scheduling a lot, on the micro benchmark from the linked bug by 3x.
这个CL删除了一些提示,这些提示在微基准测试中从链接的bug中提高了3倍。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.