Optimization 连续map/filter/fold调用的优化

Optimization 连续map/filter/fold调用的优化,optimization,functional-programming,language-agnostic,higher-order-functions,Optimization,Functional Programming,Language Agnostic,Higher Order Functions,假设我有一个大列表,我想在其中执行多个map、filter和fold/reduce调用。为了清晰和表达,这应该通过传递给map/filter/fold的小lambda函数来完成。然而,据我所知,它们实际上每次都在遍历列表,在列表上调用lambda(可能是内联的),并生成一个新列表。如果是这种情况,我可以为每个循环编写一个代码,并将所有lambda合并到它的主体中 我测量了一个简单的map/filter/reduce算法的执行时间以及Python中每个循环的相应命令,后者比我预期的快两倍多,但我知

假设我有一个大列表,我想在其中执行多个map、filter和fold/reduce调用。为了清晰和表达,这应该通过传递给map/filter/fold的小lambda函数来完成。然而,据我所知,它们实际上每次都在遍历列表,在列表上调用lambda(可能是内联的),并生成一个新列表。如果是这种情况,我可以为每个循环编写一个代码,并将所有lambda合并到它的主体中

我测量了一个简单的map/filter/reduce算法的执行时间以及Python中每个循环的相应命令,后者比我预期的快两倍多,但我知道Python在这方面不是最好的语言


我的问题是:编译器是否有可能找出它们并以某种方式将它们合并到一个循环中?有没有这样的编译器?我主要对函数式语言(Haskell、Erlang/Elixir、Scala)感兴趣,但也希望了解其他语言(Rust的实现,LINQ)。

是的,这种优化已经考虑过很多次了

使用的一个术语或方法是(也称为stream或),其目标是以
mapf等模式智能地内联迭代转换。map g=map(f.g)
。这主要需要在编译器的帮助下完成,但是可以在这些函数的“正常”实现上工作(如果它们做得有点智能的话)

另一种方法是通过累加所有中间闭包来手动执行此类内联,并且仅在实际需要值时应用组合转换(这与惰性计算密切相关,在某些语言中,如Haskell中,这将自动完成)。这样的东西可以在Scala和
Stream
s或Clojure中找到(不过它们的工作方式更复杂)。这些懒惰的东西的问题是它们更容易遇到空间问题(我听说过)

Python中的迭代器(以及C#的
IEnumerable
/LINQ之类的东西,以及Java新的
Stream
s)原理通过后一个原理工作,涉及语言提供的迭代支持(涉及一些内部状态)。这就是为什么
xs=map(print,range(10))
不会立即打印任何内容,只能遍历一次;在迭代的每一步,嵌套迭代器都会相互询问下一个值,对其进行转换,并更新其状态。(你测量的差异可能更多地是由于这一复杂的机制,而不是重复的迭代。)