2017-04-25 46 views
2

我有兩個函數的管道,這兩個函數都是重IO,並行運行在一組項目上。撰寫Task.async_stream與延續傳遞

第一個,func1很常見,而且我經常只想要func1的響應。其他時候,我想用其他函數func2來處理func1的結果。

什麼是構成Task.async_stream之間的權衡(性能/開銷,地道的煩躁),即

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

與傳遞一個延續,並使用一個Task.async_stream兩個func1func2

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

其中func1_then調用以正常func1計算結束的功能參數(Mod2.func2)?

回答

4

如果這兩個功能IO約束,那麼不應該有你的第一個例子中的任何問題:

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

如果你沒有要摺疊的兩個電話,我不會用一個延續的風格,只是他們的管道中拉姆達傳遞給Task.async_stream/3

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

或者,你可以考慮使用Flow

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

很好的答案,很高興能有更多的觀點來完成這一任務。流是否在Task.async_stream上引入額外開銷?這兩個函數是IO綁定(讀/寫文件),但集合本身通常會少於100個項目。 – Nolan330

+2

爲了跟進此事,我做了一些非常天真的**基準測試(使用找到的示例[here](http://stackoverflow.com/a/29674651/1492117)),並發現在每次500次運行中,平均次數如下: '組成Task.async:0.204734s' '管道式Task.async:0.21415s' '流速:0.25598s' 顯然與鹽的任何其他上下文的晶粒取。 – Nolan330

+0

第一個例子比第二個例子好,因爲你將函數分成兩個不同的流,第二個例子中你只有一個流,因此操作不是在同一個層次上分離的。 – PatNowak