昨日貼り付けたコードにはバグがあったので、公開後に一度修正した(loop/3)。その時にリングを構築するための別の方法も思いついたので、下に示しておく。一度にまとめてプロセスを作るのではなく、子が孫を生む方式。
construct(N) when N > 0 -> spawn(?MODULE, prepare, [N]). prepare(1) -> lib_ring:entryloop(self()); prepare(N) -> Next = spawn(?MODULE, prepare, [self(), self(), N-1]), lib_ring:entryloop(Next). prepare(First, Prev, 1) -> lib_ring:loop(Prev, First); prepare(First, Prev, N) -> Next = spawn(?MODULE, prepare, [First, self(), N-1]), lib_ring:loop(Prev, Next).
これで実行時間はさらに短縮された。プロセス数が多くなるほど差が顕著になる。
辞書方式:
N=100000, M=100 time=8.65, (9.113) seconds N=200000, M=10 time=6.41, (7.012) seconds
子孫方式:
N=100000, M=100 time=7.05, (7.573) seconds N=200000, M=10 time=1.67, (2.005) seconds
[...] ring_constructor_child.sh 上2つとは異なり、再帰的にプロセスを産み出していく実装。 [...]