代码之家  ›  专栏  ›  技术社区  ›  Brian Adams

为什么在node.js优化之后,这个javascript代码运行得更慢

  •  4
  • Brian Adams  · 技术社区  · 6 年前

    我正在创建一个解决方案 ICPC 使用javascript和 Node.js 当我遇到一个有趣的问题时:在某些情况下,我的程序在同一个数据集上运行的速度会慢一倍。

    我把它拆了下来,直到我得到了一个最小的例子来演示这个行为:

    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`);
    }
    

    这是运行的输出 node --trace-opt code.js 使用 Node 小精灵:

    [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
    

    在前三次迭代中,运行时间大约为80ms,但就在第四次迭代之前 结点 重新编译和优化一个方法,从那时起 代码运行速度大约慢3倍 .

    通常在 结点 执行运行时分析、重新编译和优化,所有操作都运行得更快。

    谁能解释为什么 结点 在这种情况下,优化会让事情变得更糟吗?


    注意,如果示例代码更改为计算 total 通过迭代而不是使用 reduce 优化提高了预期的性能(运行时间降至约60毫秒):

    let total = 0;
    for (let v of arr) total += v;
    
    0 回复  |  直到 6 年前
        1
  •  1
  •   Brian Adams    6 年前

    我提交了一份错误报告 following response 从A Chromium DEV:

    一些数组内置使用分支提示进行循环边界检查, 导致内联内置之后的所有代码都被延迟 代码。这对性能不利。

    所以这是一个众所周知的问题 TurboFan 编译程序和 a fix has been created 目前正在测试:

    此cl移除 在micro上的提示可以大大改进代码调度 从链接的bug中基准测试3倍。