Parallel processing Elixir流中的Task.async
我想在一个大列表上做一个平行映射。代码看起来有点像这样:Parallel processing Elixir流中的Task.async,parallel-processing,elixir,Parallel Processing,Elixir,我想在一个大列表上做一个平行映射。代码看起来有点像这样: big_list |> Stream.map(&Task.async(Module, :do_something, [&1])) |> Stream.map(&Task.await(&1)) |> Enum.filter filter_fun 但我正在检查流实现,据我所知,Stream.map组合函数并将组合函数应用于流中的元素,这意味着序列如下所示: big_list |> St
big_list
|> Stream.map(&Task.async(Module, :do_something, [&1]))
|> Stream.map(&Task.await(&1))
|> Enum.filter filter_fun
但我正在检查流实现,据我所知,Stream.map
组合函数并将组合函数应用于流中的元素,这意味着序列如下所示:
big_list
|> Stream.map(&Task.async(Module, :do_something, [&1]))
|> Stream.map(&Task.await(&1))
|> Enum.filter filter_fun
Stream.map Task.async ...
|> Enum.map Task.await ...
这将并行运行吗?第二个也不能满足您的需要。您可以通过以下代码清楚地看到它:
defmodule Test do
def test do
[1,2,3]
|> Stream.map(&Task.async(Test, :job, [&1]))
|> Enum.map(&Task.await(&1))
end
def job(number) do
:timer.sleep 1000
IO.inspect(number)
end
end
Test.test
您将看到一个数字,然后等待1秒,再看到另一个数字,依此类推。这里的关键是您希望尽快创建任务,因此不应该使用
懒散的Stream.map
。在该点使用eagerEnum.map
:
|> Enum.map(&Task.async(Test, :job, [&1]))
|> Enum.map(&Task.await(&1))
另一方面,您可以在等待时使用
Stream.map
,只要稍后执行一些急切的操作,如过滤器
。这样,等待将与您可能对结果进行的任何处理交织在一起。Elixir 1.4提供了一个新函数,该函数将返回一个流,该流在可枚举项中的每个项上同时运行给定函数
还可以使用:max_concurrency
和:timeout
选项参数指定最大工作进程数和超时
请注意,您不必等待此任务,因为函数返回一个流,因此您可以使用或使用
这将使您的示例同时运行:
big_list
|> Task.async_stream(Module, :do_something, [])
|> Enum.filter(filter_fun)
你可以试试
UPD
或者最好使用阅读此-