Apo*_*orv 5 scala compiler-optimization
Scala 有一种使用mapconstruct将集合转换为另一个集合的惊人方法。
val l = List(1, 2, 3, 4)
l.map(_*_)
Run Code Online (Sandbox Code Playgroud)
将返回列表中元素的平方 l
我遇到了多个地图链接在一起的各种情况,比如,
val l = List(1, 2, 3, 4)
val res = l.map(_ * _).map(_ + 1).filter(_ < 3)
Run Code Online (Sandbox Code Playgroud)
我相信下面发生的事情等同于下面的事情。
val l = List(1, 2, 3, 4)
val l1 = l.map(_*_)
val l2 = l1.map(_ + 1)
val res = l2.filter(_ < 3)
Run Code Online (Sandbox Code Playgroud)
创建l1和l2如果集合过大可能会导致内存问题。为了解决这个问题,Scala 编译器有什么优化吗?
val l = List(1, 2, 3, 4)
val res = l1.map( _*_ + 1).filter(_ < 3)
Run Code Online (Sandbox Code Playgroud)
一般来说,如果f, g,h是函数
val l = List(/*something*/)
val res = l.map(f(_)).map(g(_)).map(h(_))
Run Code Online (Sandbox Code Playgroud)
可以转换成
val res = l.map(f _ andThen g _ andThen h _)
Run Code Online (Sandbox Code Playgroud)
不,因为这需要编译器了解map专门实现它的标准库类的语义并对其进行处理(因为没有人阻止您编写不成立的类)。有一项研究提案可能最终会实现这一点……最终。
还有Scala-Blitz优化了一些收集操作,但是融合和森林砍伐在本次演示中被列为未来的工作,我认为它们还没有实现。
正如 Steve Waldman 的回答所说,使用Stream(或者更好的是,Iterator)可以有所帮助,但它不会完全消除中间集合。