Ниже приведен рабочий пример того, как вы могли бы достичь параллелизма для своих довольно забавных задач по выполнению операций приращения 1000000000 - на случай, если вам интересно, как это можно сделать.
Код ниже порождает 100 процессов эликсира, соответствующих вашей внешней петле. Внутренний код - эти 2 вложенных цикла - (записанные в более идиоматической форме с использованием Enum.reduce
см. ), таким образом, выполняется одновременно (насколько это возможно для виртуальной машины). Результаты каждого процесса отправляются выделенному процессу получателя, который начинает отсчет, начиная с 100, всякий раз, когда он получает новый результат. Каждый промежуточный итог добавляется к общему итогу, который затем распечатывается после получения 100 промежуточных итогов.
Для проверки: сохраните код в виде файла nested.ex
и скомпилируйте в оболочке Elixir, используя c nested.ex
. Запустите его в этой оболочке, используя Main.main
. Вы должны увидеть следующий вывод:
iex(4)> Main.main
:ok
total = 1000000000
с ok
, идущим за несколько секунд до total
. Вы также должны испытать многоядерный процессор.
defmodule Main do
def main( ) do
pid = spawn fn -> Receiver.loop( 100,0 ) end
1..100 |> Enum.each( fn x -> spawn (fn -> Nested.run(pid) end ) end)
end
end
#################################
defmodule Nested do
def run(pid) do
sub_total=
Enum.reduce( 1..1000, 0, fn x, acc_n -> acc_n +
Enum.reduce( 1..10000, 0, fn y, acc_m -> acc_m + 1 end )
end )
send pid, sub_total
Process.exit(self(), :kill )
end
end
#################################
defmodule Receiver do
def loop(0, total) do
IO.puts "total = #{total}"
Process.exit(self(), :kill )
end
#
def loop(count_down, total ) do # count down to zero collecting totals
receive do
sub_total ->
loop(count_down-1, sub_total + total)
end
end
end
#################################
Параллелизм можно получить, чтобы получить преимущество по сравнению с чистым параллелизмом, разумно преобразовав из простого spawn
в Node.spawn
см. Документы
Тест неформальной скорости
Тестирование на моем компьютере Win10, который сообщает:
Erlang/OTP 20 [erts-9.0] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:10]
Interactive Elixir (1.8.2) ..
Код, который я здесь привожу, вычисляет результат в 16 с, где, как и у @Hauleth, это занимает более 10 минут - поскольку его, похоже, выделяется только одно ядро, где мое получает все 4.