2016-09-22 11 views
0

次の2つのコードブロックは、パフォーマンス面で同等ですか?複数のマップ()最適化のスケーリング

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

と...

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

具体的には、コードを最適化し、常にで上記のスニペットの両方のための単一のマップにのみジョブを実行しようとして火傷されますか?マップ関数がgetName/splitよりも複雑な場合はどうでしょうか?

IMO(およびはるかに複雑なマップ関数の場合)最初の例は読みやすくなっています。しかし、私はそれが効率の悪いランタイムの実行につながる可能性があることを心配しています。

+0

ところで、複数のmap()関数が次々に(そしてそれらの間に他の関数がなく)あると、それらはコンパイラ/オプティマイザと単一のマップのみのジョブが実行されます。私はちょうどその証拠が必要です! – Gevorg

答えて

2

2つの関数は、バイトコード/スカラック層では折りたたまれませんが、もっと重要なことに、スケーリングは常にそれらをhadoopの1つのマップタスクに崩壊させます。実際、すべてのマップライクな演算子(map、flatMap、filterなど)は1つのマップタスク、またはreduceタスクの最後にまとめられます。

したがって、2つの例では、ハングープに同じDAGがありますが、唯一の違いは追加の関数呼び出しオーバーヘッドです。

これらの関数を別々に呼び出すオーバーヘッドは、スケーリングジョブで実行されるシリアライゼーション/デシリアライゼーションやIOと比較してパフォーマンスのボトルネックになることはほとんどありません。また、ホットスポットのVMがこれをネイティブ命令にJITすることも可能です。

大規模なプロファイリングを行っていない限り、これがボトルネックであることが判明していない限り、私は可読性を重視することをお勧めします(私は非常に驚くでしょう)。

+0

コードを実行しなくてもDAGを見て回る方法はありますか?コードを与えられたら、デプロイメントを行うことなく、いくつのマッパー/レデューサーが実行されるのか知りたいです。 – Gevorg

+0

--tool.graphをスケーリングジョブに渡すことでDAGを見ることができます.DAGを含むファイルを書き出すと思います。それは入力データのサイズに依存するので、num mappers/reducersは表示されません。 –

関連する問題