【发布时间】:2019-12-23 06:49:39
【问题描述】:
这是一个关于 Scala 编译器的问题。
假设我有一个列表,并且我通过几个地图和平面地图来转换该列表。
val myList = List(1,2,3,4,5)
val transformed = myList.map(_+1).map(_*2).flatmap(x=>List(x-1,x,x+1))
假设我再对其进行一些改造。
val moreTransformed = transformed.map(_-2).map(_/5).flatMap(x=>List(x/2,x*2))
我的问题可以分为两部分
在为
transformed生成 val 时,底层 Java 字节码是否会创建中间列表?我指的是在transformed的计算中对 map 和 flatMap 的连续调用。 Scala 编译器可以将这些调用组合成一个 flatMap 吗?如果我在对象列表上进行操作,这将需要创建更少的中间对象。如果编译器很幼稚,只是简单地创建中间对象,则可能会为涉及长链 map 和 flatMap 的计算带来相当大的开销。让我们说在上面创建的两个 val 中,我只在进一步计算中使用
moreTransformed(第二个 val)。也就是说,我只在moreTransformed的计算中使用了transformed(第一个val),没有其他地方。 Scala 编译器是否足够聪明,不会为transformed创建列表而只计算moreTransformed?组合transformed和moreTransformed中的所有函数是否足够聪明,从而只生成一个List,即moreTransformed的值?
【问题讨论】:
-
除了已经告诉过的内容。你不应该真正关心这个。 - 除非,您已经进行了基准测试并将其识别为瓶颈。我就是这种情况,可以使用许多优化。 - 对于第一个示例,以
.iterator开始链并以`toList, that way it will be just one iteration. - for the second case, consider a **LazyList** - Finally, if all your program is a big data pipeline, consider using **Streaming** _(AkkaStreams,fs2,monix.Observable` 或zio.ZStream)_ 结束链,或者如果数据太大,请考虑@ 987654338@ 或Flink.
标签: scala monads functor scalac scala-compiler