githubに登録して、『プログラミングErlang』8章11の練習問題2のコードを載せてみた。初git。
http://github.com/tkyk/erlang-exercise—/tree/master
8章までの知識と覚えたばかりのmakeの知識を総動員して、極力凝った構成にしてある。コードは役割ごとに複数のモジュールに分割して、特にリングを構築する部分は実行時にアルゴリズムを切り替えられるようになっている。いわゆるストラテジーパターン。
次のようにコードを落としてきてmakeを実行すると
git clone git://github.com/tkyk/erlang-exercise---.git make
erlのコンパイルが行われた後、各アルゴリズムに対応した3つのシェルスクリプトが生成される。いずれも今まで日記に書いてきたもの。
- ring_constructor_list.sh
一番最初に作ったリストによる実装。クソ遅い。 - ring_constructor_dict.sh
listをdictに変えて作り直したもの。 - ring_constructor_child.sh
上2つとは異なり、再帰的にプロセスを産み出していく実装。
引数としてN(プロセス数)とM(メッセージを回す数)を与えて実行すると、erlが起動されて計算が実行され、実行時間が表示される。また make run とすると3つのスクリプトそれぞれに、何通りかのNとMを与えて自動的に実行する。
$ ./ring_constructor_child.sh 1000 1000 Constructor=ring_constructor_child, N=1000, M=1000 time=0.55, (0.563) seconds
なお、この練習問題では「リング」の定義が曖昧なので、自分なりの判断で以下の条件を課している。
- メッセージの転送を開始できるのは始点となるプロセスのみ
- 始点以外のプロセスは自分の”前”のプロセスを厳密に認識して、他からのメッセージは受け取らない
この条件により実装が複雑になっている部分があるので、条件を外して単純化したバージョンを別ブランチで用意した。
http://github.com/tkyk/erlang-exercise—/tree/ignore_msg_sender
lib_ring.erl以外の内容はmasterブランチと全く同じで、使い方も同じで、実行速度もほとんど同じである。
……
この練習問題にここまでこだわる理由はどこにもないのだが、Erlangに飽きないうちにできるだけのことはやっておきたい。