2016-09-22 2 views
0

Sind die folgenden zwei Codeblöcke gleichwertig in Bezug auf die Leistung?Verbrühung 'multiple map()' Optimierung

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

und ...

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

Insbesondere wird Verbrühungen geht um den Code zu optimieren und eine einzelne Karte nur Job für beide oben die Schnipsel zu allen Zeiten ausführen? Was ist, wenn die Kartenfunktionen viel komplexer sind als GetName/Split?

IMO (und für weit komplexere Kartenfunktionen) ist das erste Beispiel besser lesbar. Ich bin jedoch besorgt, dass dies zu einer weniger effizienten Laufzeitausführung führen könnte.

+0

Übrigens ist meine Vermutung, dass, wenn es mehrere map() - Funktionen nacheinander (und ohne irgendwelche anderen Funktionen dazwischen) gibt, sie vom Compiler/Optimizer und einer einzigen in eine einzige zusammengelegt werden Nur-Karten-Job wird ausgeführt. Ich brauche nur einen Beweis dafür! – Gevorg

Antwort

2

Die beiden Funktionen werden nicht in der Bytecode/scalac-Ebene zusammengeführt, aber noch wichtiger ist das Verbrühen, wenn sie in hadoop zu einer einzigen Map-Aufgabe zusammengefasst werden. In der Tat werden alle Ihre kartenähnlichen Operatoren (map, flatMap, Filter usw.) in eine Map-Aufgabe oder sogar in das Ende einer Reduzierungsaufgabe zusammengefasst.

So haben Ihre beiden Beispiele die gleiche DAG in Hadoop, der einzige Unterschied ist einige zusätzliche Funktion Anruf Overhead.

Es ist sehr unwahrscheinlich, dass der Aufwand für den separaten Aufruf dieser Funktionen einen Leistungsengpass im Vergleich zur Serialisierung/Deserialisierung und IO in Ihrem Verbrühungsjob darstellt. Und es ist auch möglich, dass der Hotspot vm einige davon auch in native Befehle eingibt.

Ich würde auf jeden Fall für die Lesbarkeit empfehlen, es sei denn, Sie haben umfangreiche Profiling getan und festgestellt, dass dies ein Engpass (ich wäre sehr überrascht).

+0

Gibt es eine Möglichkeit, die DAG anzusehen, ohne den Code ausführen zu müssen? Angesichts eines Stück Code würde ich gerne wissen, wie viele Mapper/Reducer laufen werden, ohne durch die Bereitstellung gehen zu müssen. – Gevorg

+0

Sie können die DAG sehen, indem Sie --tool.graph an Ihren Verbrühungsjob übergeben, ich denke, dass sie eine Datei mit der DAG schreiben wird. Das zeigt Ihnen jedoch nicht die Num-Mapper/Reducer, da dies von der Größe der Eingabedaten abhängt. –