以下两个代码块在性能方面是否相等?
val input: TypedPipe[Person] = ....
input
.map(_.getName)
.map(_.split(" "))
和
val input: TypedPipe[Person] = ....
input
.map(_.getName.split(" "))
具体来说,Scalding是否会优化代码并始终为上面两个片段执行一个仅映射的作业?如果map函数比getName/split复杂得多怎么办?
在我看来(对于更复杂的地图函数),第一个例子更具可读性。但是,我担心它可能会导致运行时执行效率降低。
这两个函数不会在字节码/标量层折叠,但更重要的是,在hadoop中,折叠总是会将它们折叠成一个单独的map任务。事实上,所有类似map的操作符(map, flatMap, filter等)将被折叠到一个map任务中,甚至可以折叠到reduce任务的末尾。
所以你的两个例子在hadoop中会有相同的DAG,唯一的区别是一些额外的函数调用开销。
与序列化/反序列化和IO相比,单独调用这些函数的开销不太可能成为性能瓶颈。热点虚拟机也有可能将其中一些JIT到本机指令中。
我绝对建议你追求可读性,除非你做了大量的分析,发现这是一个瓶颈(我会非常惊讶)。