【问题标题】:Does JavaScript optimise multiple pure filters/maps/etc?JavaScript 是否优化了多个纯过滤器/地图/等?
【发布时间】:2019-04-14 22:55:42
【问题描述】:

我有这个以函数式风格编写的 JavaScript 代码:

someArray
  .filter((element) => element)
  .map((element) => element.property)
  .map((property) => doSomethingWithIt)

现在,一个简单的实现会在数组上循环 3 次——filtermap 各循环一次——但优化器应该能够将它优化到一个执行多个操作的循环,假设所有函数都是纯的。

(大多数?)JavaScript 引擎会对此进行优化;还是需要手动优化?

编辑:我认为优化的只是将其减少到一个循环:

someArray.reduce((acc, element) => {
  if(!element) {
    return acc
  }

  return acc.push(doSomethingWithIt(element.property))
}, [ ])

【问题讨论】:

  • 你的两个问题可能都不是。地图规范没有提及展开ecma-international.org/ecma-262/6.0/#sec-array.prototype.map。而且你可能不需要优化两张地图
  • 我无法谈论实际的实现细节,但我只想说这肯定不是性能瓶颈。
  • 创建一个性能测试,看看会告诉你什么

标签: javascript performance compiler-optimization


【解决方案1】:

优化器应该能够将其优化到一个循环执行多个操作。

不,不应该!这种优化可能会改变代码的行为。

考虑一个双 map,其中每个 map 中的操作具有可观察到的副作用:

let arr = [1, 2, 3];
arr.map((x) => { console.log("foo", x); return x })
   .map((y) => { console.log("bar", y); return y });

记录与“优化”版本不同的消息序列:

let arr = [1, 2, 3];
arr.map((x) => {
    console.log("foo", x);
    console.log("bar", x);
    return x;
});

【讨论】:

  • 好点。而且没有办法告诉 JS 一个函数是纯的,对吧?它有没有机会自己解决这个问题?
【解决方案2】:

除非您想在数组中包含 undefined,否则您无法删除 filter 调用 - 但是,您可以使用解构将两个 map 调用合二为一:

someArray.filter(element => element).map(({ property }) => doSomething(property));

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-02-02
    • 2018-07-08
    • 2016-12-23
    • 1970-01-01
    • 1970-01-01
    • 2020-10-25
    • 1970-01-01
    • 2014-09-06
    相关资源
    最近更新 更多