複数のデータに対して、同じ処理を適用する場合、Task.Supervisor.async_stream
を利用すると、個々の処理を並列で実行してくれます。CPU を存分に酷使してくれます。
defmodule Sample do require Integer @doc """ Collatz conjecture see [Collatz conjecture - Wikipedia](https://en.wikipedia.org/wiki/Collatz_conjecture) """ def collatz(n) when is_integer(n) and n > 0, do: collatz(n, []) def collatz(1, acc), do: [1 | acc] |> Enum.reverse() |> Enum.join(",") def collatz(n, acc) when Integer.is_odd(n), do: collatz(n * 3 + 1, [n | acc]) def collatz(n, acc), do: collatz(div(n, 2), [n | acc]) def run do # Task.Supervisor をスタートします Task.Supervisor.start_link(name: Task.SampleSupervisor) Task.SampleSupervisor |> Task.Supervisor.async_stream(1..10, Sample, :collatz, [], orderd: false, timeout: :infinity) |> Enum.map(&IO.inspect/1) end end
Task.Supervisor.async_stream
はストリームを生成するので、結果を得るには Enum.to_list/1
などを利用して要素を評価する必要があります。ここでは Enum.map/2
を使って個々の要素を IO.inspect/1
で出力しています。
実行。
$ mix run -e 'Sample.run()' {:ok, "1"} {:ok, "2,1"} {:ok, "3,10,5,16,8,4,2,1"} {:ok, "4,2,1"} {:ok, "5,16,8,4,2,1"} {:ok, "6,3,10,5,16,8,4,2,1"} {:ok, "7,22,11,34,17,52,26,13,40,20,10,5,16,8,4,2,1"} {:ok, "8,4,2,1"} {:ok, "9,28,14,7,22,11,34,17,52,26,13,40,20,10,5,16,8,4,2,1"} {:ok, "10,5,16,8,4,2,1"}
個々の結果は、処理が成功した場合は :ok
と処理結果のペアがタプルで返ります。