私は現在、ウェブサイトexerciseism.ioでエリクシルを学習しています。 私は問題である「倍数の和」を持っていた:マルチプロセスの効率が悪い
、我々は3、5、6を得るまでが、3または5のいずれかの 倍数である20を含んでいない、我々はすべての自然数を一覧表示した場合と9、10、12、15、およびこれらの倍数の18 合計が78
である私は、このコードでこの問題は解決:
defmodule SumOfMultiples do
@doc """
Adds up all numbers from 1 to a given end number that are multiples of the factors provided.
"""
@spec to(non_neg_integer, [non_neg_integer]) :: non_neg_integer
def to(limit, factors) do
1..limit - 1
|> Enum.reduce([], fn(x,acc) ->
is_multiple? = factors
|> Enum.map(&(rem(x,&1) === 0))
|> Enum.any?
if is_multiple?, do: [x|acc], else: acc
end)
|> Enum.sum
end
end
をしかし、私は最近、私が望んでいたエリクサー内のプロセスを発見しますpを解くマルチプロセスの問題:
defmodule SumOfMultiples do
@doc """
Adds up all numbers from 1 to a given end number that are multiples of the factors provided.
"""
@spec to(non_neg_integer, [non_neg_integer]) :: non_neg_integer
def to(limit, factors) do
me = self
1..limit - 1
|> Enum.map(fn(x) ->
spawn(SumOfMultiples, :is_multiple?, [x, factors, me])
end)
|> Enum.map(fn(_) ->
receive do
{true, n} -> n
{false, n} -> 0
end
end)
|> Enum.sum
end
def is_multiple?(n, factors, pid) do
flag = factors
|> Enum.map(&(rem(n,&1) === 0))
|> Enum.any?
send pid, {flag, n}
end
end
私はそれを解決するためにパラレルマップを使用します。作品ですが、それはシングルプロセスバージョンより4倍少ないです。
他の人がなぜこのようなパフォーマンスの違いがあるのか説明できたら、残りのexerciseism.io問題をマルチプロセスバージョンで解決する予定があるので、非常に役に立ちます。
ありがとうございました!
---------------------更新---------------------
ありがとうございました!それはあなたが正しいことが判明!説明してくれてありがとう!ここに私の新しい実装があります:
defmodule SumOfMultiples do
@doc """
Adds up all numbers from 1 to a given end number that are multiples of the factors provided.
"""
@spec to(non_neg_integer, [non_neg_integer]) :: non_neg_integer
def to(limit, factors) do
me = self
1..limit - 1
|> Stream.chunk(200, 200, Stream.cycle([0]))
|> Enum.map(fn(x) ->
spawn(SumOfMultiples, :do_to, [x, factors, me])
end)
|> Enum.map(fn(_) ->
receive do
n -> n
end
end)
|> Enum.sum
end
def do_to(list, factors, pid) do
result = list
|> Enum.reduce([], fn(x,acc) ->
is_multiple? = factors
|> Enum.map(&(rem(x,&1) === 0))
|> Enum.any?
if is_multiple?, do: [x|acc], else: acc
end)
|> Enum.sum
send pid, result
end
end
最大は、1つのプロセスよりも40%高速です!わーい !
Stream.chunk_by()はあなたの友だち – GavinBrelstaff