【问题标题】:Array filtering and object conversion: what is fastest and what other considerations matter?数组过滤和对象转换:什么是最快的以及其他哪些考虑因素很重要?
【发布时间】:2017-07-28 09:57:21
【问题描述】:

假设我需要将数组转换为对象,并在此过程中进行一些过滤。

我有两种方法,一种使用可链接的函数方法,例如 .map.filter.reduce,另一种使用老式的 for-loop 循环遍历数组并改变对象。

功能方式:

const output = fields
    .filter(field => field.required)
    .map(field => field.name)
    .reduce((acc, cur, i) => {
      acc[cur] = false;
      return acc;
    }, {});

老派for-loop方式:

let output2 = {};
for (var i = 0; i < fields.length; i++) {
  if (fields[i].required) {
    output2[fields[i].name] = false;
  }
}

我更喜欢函数式方法,因为我认为它可以带来更好的可读性代码。然而,我很惊讶(也有点失望)得知功能性方法始终比非功能性的老派for-loop 转换方式慢。请找the JSBench here

我认为这里可能有几件事:

  1. 我是个白痴,我的实现有缺陷,可以优化。
  2. “JSBench 并不是衡量性能的最佳方法。工具 X、Y、Z 是衡量性能的更好方法”
  3. “函数式方法的性能损失是值得的,因为您可以使用 const,它具有其他有益方面,例如(半)不变性。”

有人愿意称重吗?

您可以在 JSBench 链接中找到我正在使用的测试数组。

【问题讨论】:

  • 不,重复调用的几个函数永远不会胜过 for 循环。请注意,您将使用第一个迭代 3 次,而第二个迭代一次。我认为 lodash 链能够编写第一个,但实际上是第二个(不太舒尔)
  • @Jonasw 好吧,实际上...jsben.ch/ANYb1 似乎函数式方法可以更快
  • 确实如此。不过,我注意到一些有点奇怪的东西:与仅具有优化功能和 for 循环方法的 JSBench 相比,具有 3 种方法的 JSBench 为优化的功能实现提供了更好的结果。三个实现:jsben.ch/ANYb1 两个实现:jsben.ch/fPcwS
  • @pablo 可能正在进行一些好的内联......

标签: javascript arrays performance


【解决方案1】:

“filter map reduce”循环同一个数组 3 次。 所以一个 for 循环总是更快。 但减少它自己的作品很好

    const output = fields
    .reduce((acc, cur, i) => {
      if(cur.required){
        acc[cur.name] = false;
      }
      return acc;
    }, {});

【讨论】:

  • 确实如我所料,我是个白痴。当然,这是一个更好的方法。根据 JSBench,此实现非常接近 for-loop 方法:100% 与 99% 并在大多数运行中勉强获胜。
【解决方案2】:

另一种功能性方式,可能快三倍:

const output = fields
.reduce((acc, cur) => {
  if(curr.required) acc[cur.name] = false;
  return acc;
}, {});

而且你也可以使用地图(以后会有更好的表现):

const output=new Map(fields.map(el=>el.required?[el.name,false]:[0,false]));
output.delete(0);

【讨论】:

    【解决方案3】:

    您可以考虑将Object.assignArray#mapspread syntax ... 结合使用。

    const output = Object.assign({}, ...fields.map(o => (o.required && { [o.name]: false })));
    

    【讨论】:

    • 我喜欢这种做法,很干净。但是在与for-loop 的一对一中,for-loop 获胜:jsben.ch/T5x7X
    • 只是一个想法,为您提供更多可能性。
    • 谢谢你,非常感谢@nina :)
    猜你喜欢
    • 1970-01-01
    • 2016-08-22
    • 1970-01-01
    • 1970-01-01
    • 2012-12-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多