【发布时间】:2021-08-17 11:40:05
【问题描述】:
我在工作日主要使用 TypeScript,在应用函数式模式时,我经常看到如下模式:
const someArray = anotherArray.filter(filterFn).map(transformFn)
此代码将过滤所有anotherArray 的项目,然后再次遍历过滤后的列表(如果没有过滤任何项目,则可能相同)并映射事物。换句话说,我们对数组进行了两次迭代。
这种行为可以通过使用reduce 对数组进行“单次传递”来实现:
const someArray = anotherArray.reduce((acc, item) => {
if (filterFn(item) === false) {
return acc;
}
acc.push(item);
return acc;
}, [])
我想知道这种优化是否是编译器(在 TS 世界中)知道自动执行的操作,以及此类优化是否在更“功能优先”的语言(例如 Clojure 或 Haskell)中自动完成。例如,我知道函数式语言通常使用尾递归进行优化,所以我也想知道“过滤然后映射”的情况。这是编译器实际做的事情吗?
【问题讨论】:
-
在存在副作用的情况下,转换不一定等效。
-
这取决于纯洁和懒惰。 Layzness 在
map/reduce方面免费为您提供了更高的效率,但要懒惰并额外执行基于编译器的循环融合纯度是一项要求。只提供惰性数据结构但不像 Clojure 那样纯粹的语言需要转换器或其他方式来允许手动循环融合。 -
+1 我不时想知道同样的问题。此外,是否有任何编译器在这种纯流中利用潜在的并行性? :)
标签: functional-programming compiler-optimization