Chain.counter/1
各プロセスが実行する関数
プロセス生成時に次のプロセスのPIDを保持している
メッセージを受け取ったら、次のプロセスに n + 1 の結果を送る
Chain.create_processes/1
Enum.reduce/3でやっていること- n個のプロセスを作り、最後に作ったプロセスのPIDを返す
- 各プロセスに次に呼び出すプロセスのPIDを持たせている
- 最後に作ったプロセスに
n = 0としてメッセージを送信 - 結果を待つ
Enum.reduce(enumerable, acc, fun)
acc を初期値として fun(element, acc) を実行し、その結果を次の acc として使用する
receive ブロックでもガード節が使える
:timer.tc(module, function, arguments)
module の関数 function を引数として arguments を渡して実行し、以下のtupleを返す
`{かかった時間(ミリ秒), 処理結果}
goh@goh% elixir -r spawn/chain.ex -e "Chain.run(10)"
{9542, "Result is 10"}
goh@goh% elixir -r spawn/chain.ex -e "Chain.run(10)"
{4376, "Result is 10"}
goh@goh% elixir -r spawn/chain.ex -e "Chain.run(10)"
{4381, "Result is 10"}
goh@goh% elixir -r spawn/chain.ex -e "Chain.run(100)"
{5431, "Result is 100"}
goh@goh% elixir -r spawn/chain.ex -e "Chain.run(100)"
{6868, "Result is 100"}
goh@goh% elixir -r spawn/chain.ex -e "Chain.run(100)"
{5568, "Result is 100"}
goh@goh% elixir -r spawn/chain.ex -e "Chain.run(1000)"
{14834, "Result is 1000"}
goh@goh% elixir -r spawn/chain.ex -e "Chain.run(1000)"
{15233, "Result is 1000"}
goh@goh% elixir -r spawn/chain.ex -e "Chain.run(1000)"
{16389, "Result is 1000"}
goh@goh% elixir -r spawn/chain.ex -e "Chain.run(10000)"
{110738, "Result is 10000"}
goh@goh% elixir -r spawn/chain.ex -e "Chain.run(10000)"
{109732, "Result is 10000"}
goh@goh% elixir -r spawn/chain.ex -e "Chain.run(10000)"
{103310, "Result is 10000"}
goh@goh% elixir -r spawn/chain.ex -e "Chain.run(400000)"
15:58:58.830 [error] Too many processes
** (SystemLimitError) a system limit has been reached
:erlang.spawn(Chain, :counter, [#PID<0.90.8>])
spawn/chain.ex:12: anonymous fn/2 in Chain.create_processes/1
(elixir) lib/enum.ex:2967: Enum.reduce_range_inc/4
spawn/chain.ex:10: Chain.create_processes/1
(stdlib) timer.erl:197: :timer.tc/3
spawn/chain.ex:26: Chain.run/1
(stdlib) erl_eval.erl:677: :erl_eval.do_apply/6
goh@goh% elixir --erl "+P 1000000" -r spawn/chain.ex -e "Chain.run(400000)"
{3966479, "Result is 400000"}
goh@goh% elixir --erl "+P 1000000" -r spawn/chain.ex -e "Chain.run(400000)"
{3900263, "Result is 400000"}
goh@goh% elixir --erl "+P 1000000" -r spawn/chain.ex -e "Chain.run(400000)"
{3798163, "Result is 400000"}
goh@goh% elixir --erl "+P 1000000" -r spawn/chain.ex -e "Chain.run(1000000)"
{8905634, "Result is 1000000"}
goh@goh% elixir --erl "+P 1000000" -r spawn/chain.ex -e "Chain.run(1000000)"
{8781462, "Result is 1000000"}
goh@goh% elixir --erl "+P 1000000" -r spawn/chain.ex -e "Chain.run(1000000)"
{8554100, "Result is 1000000"}実行時間 >> 起動時間 ならば、実行時間はプロセス数に比例する
各プロセスは状態を持つことができる ≒ オブジェクト指向システムのオブジェクト => ココまでの説明では、プロセスを生成する単位が関数なので、オブジェクトというよりは、クロージャー同士が通信しているようなイメージが浮かんだ メッセージをやりとりするから「オブジェクトに似ている」ということなのだろうか?