【发布时间】: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。
我认为这里可能有几件事:
- 我是个白痴,我的实现有缺陷,可以优化。
- “JSBench 并不是衡量性能的最佳方法。工具 X、Y、Z 是衡量性能的更好方法”
- “函数式方法的性能损失是值得的,因为您可以使用
const,它具有其他有益方面,例如(半)不变性。”
有人愿意称重吗?
您可以在 JSBench 链接中找到我正在使用的测试数组。
【问题讨论】:
-
不,重复调用的几个函数永远不会胜过 for 循环。请注意,您将使用第一个迭代 3 次,而第二个迭代一次。我认为 lodash 链能够编写第一个,但实际上是第二个(不太舒尔)
-
@Jonasw 好吧,实际上...jsben.ch/ANYb1 似乎函数式方法可以更快
-
确实如此。不过,我注意到一些有点奇怪的东西:与仅具有优化功能和 for 循环方法的 JSBench 相比,具有 3 种方法的 JSBench 为优化的功能实现提供了更好的结果。三个实现:jsben.ch/ANYb1 两个实现:jsben.ch/fPcwS
-
@pablo 可能正在进行一些好的内联......
标签: javascript arrays performance