2017-04-25 3 views
2

Ich habe eine Pipeline von zwei Funktionen, die beide IO-Heavy sind, auf einer Sammlung von Elementen gleichzeitig ausgeführt wird.Composing Task.async_stream vs. Fortsetzung

Die erste, func1, ist sehr häufig, und oft will ich nur die Antwort von func1 allein. Andere Zeiten, würde ich gerne das Ergebnis von func1 mit einer anderen Funktion, func2 verarbeiten.

Was ist das Trade-offs (Leistung/Overhead, idiomatische-ness) zwischen Task.async_stream Komponieren, das heißt

enum 
|> Task.async_stream(Mod1, :func1, []) 
|> Task.async_stream(Mod2, :func2, []) 
... 

gegen eine Fortsetzung vorbei und mit einer Task.async_stream sowohl für func1 und func2 dh

enum 
|> Task.async_stream(Mod1, :func1_then, [&Mod2.func2/arity]) 
... 

wo func1_then den Funktionsparameter aufruft (Mod2.func2) am Ende der normalen func1 Berechnung?

Antwort

4

Wenn beide Funktionen IO gebunden ist, dann sollte es kein Problem mit dem ersten Beispiel sein:

enum 
|> Task.async_stream(Mod1, :func1, []) 
|> Task.async_stream(Mod2, :func2, []) 

Wenn Sie die beiden Anrufe kollabieren wollte, würde ich nicht eine Fortsetzung Stil verwenden, nur Pipeline sie in einem Lambda bestanden Task.async_stream/3:

enum 
|> Task.async_stream(fn x -> x |> Mod1.func1() |> M2.func2() end) 

Alternativ könnten Sie mit Flow:

enum 
|> Flow.from_enumerable() 
|> Flow.map(&Mod1.func1/1) 
|> Flow.map(&Mod2.func2/1) 
|> Flow.run() 
+0

Große Antwort, froh, mehr Perspektiven auf dem Weg zu haben, dies zu erreichen. Führt der Fluss zusätzlichen Overhead über Task.async_stream ein? Die zwei Funktionen sind IO gebunden (Lesen/Schreiben von Dateien), aber die Sammlung selbst wird in der Regel weniger als 100 Elemente sein. – Nolan330

+2

Um dies zu verfolgen, habe ich ein ** sehr naives ** Benchmarking durchgeführt (mit Beispiel gefunden [hier] (http://Stackoverflow.com/a/29674651/1492117)) und festgestellt, dass in 500 Läufen von jedem der Durchschnittszeiten waren wie folgt: 'Komponiert Task.async: 0.204734s' ' Piped Task.async: 0.21415s' 'Fluss: 0.25598s' Offensichtlich mit einem Körnchen Salz für einen anderen Kontext genommen werden. – Nolan330

+0

Das erste Beispiel ist besser als das zweite, weil Sie Funktionen in zwei verschiedene Ströme aufteilen, im zweiten Beispiel haben Sie nur einen Strom, daher sind die Operationen nicht auf demselben Niveau isoliert. – PatNowak