【问题标题】:Scalding 'multiple map()' optimization烫伤'multiple map()'优化
【发布时间】:2016-09-22 14:13:14
【问题描述】:

以下两个代码块在性能方面是否等效?

val input: TypedPipe[Person] = ....
input
  .map(_.getName)
  .map(_.split(" "))

还有……

val input: TypedPipe[Person] = ....
input
  .map(_.getName.split(" "))

具体来说,Scalding 是否会始终优化代码并为上面的两个 sn-ps 执行一个仅映射作业?如果地图函数比 getName/split 复杂得多怎么办?

IMO(以及更复杂的地图功能)第一个示例更具可读性。但是,我担心它可能会导致运行时执行效率降低。

【问题讨论】:

  • 顺便说一句,我的猜测是,如果有多个 map() 函数一个接一个(并且它们之间没有任何其他函数),那么它们将被编译器折叠成一个/optimizer 和一个仅地图作业将被执行。我只需要证明!

标签: java scala mapreduce cascading scalding


【解决方案1】:

这两个函数不会在字节码/scalac 层折叠,但更重要的是,在 hadoop 中,scalding 总是会将它们折叠成单个 map 任务。事实上,所有类似 map 的操作符(map、flatMap、filter 等)都会被折叠成一个 map 任务,甚至是一个 reduce 任务的结尾。

因此,您的两个示例在 hadoop 中将具有相同的 DAG,唯一的区别是一些额外的函数调用开销。

与烫伤工作中的序列化/反序列化和 IO 相比,单独调用这些函数的开销不太可能成为性能瓶颈。并且热点虚拟机也有可能会将其中的一些 JIT 转换为本地指令。

我绝对建议您考虑可读性,除非您进行了广泛的分析并发现这是一个瓶颈(我会感到非常惊讶)。

【讨论】:

  • 有没有办法“看看” DAG 而无需运行代码?给定一段代码,我想知道将运行多少个映射器/减速器而无需通过部署。
  • 您可以通过将 --tool.graph 传递给您的烫伤作业来查看 DAG,我认为它会写出一个包含 DAG 的文件。不过,这不会向您显示 num mappers / reducers,因为这取决于输入数据的大小。
猜你喜欢
  • 2014-06-19
  • 1970-01-01
  • 1970-01-01
  • 2013-06-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-16
  • 1970-01-01
相关资源
最近更新 更多