ラベル Erlang の投稿を表示しています。 すべての投稿を表示
ラベル Erlang の投稿を表示しています。 すべての投稿を表示

2013年5月11日土曜日

ゆとりさんが鮨を奢ってくれるそうなので、感謝の気持を込めて、たくさんのプロセスに「sushi」と言わせてみた

・これはなんですか?

ゆとりAdvent Calendarの11日目です。


・なんで書いているんですか?

ゆとりさんが鮨を奢ってくれるというので、感謝の気持を込めて書いています。


・実行方法は?

  • Eshellを開きます。
  • yutori.erlをコンパイルもしくはロードします。
  • yutori:call()を実行します。
  • yutori:sushi(プロセス数, 回数)を入力します。


・実行結果は?

こんなかんじ。




・結論

僕にはゆとりがないので、ゆとりさんを待たずにyutori:sushi(プロセス数, 回数)を実行してしまいました。




ゆとりなんてなかったんや!

コードはこちらからどうぞ。

2013年5月2日木曜日

リング上のプロセスでメッセージを伝達する

Erlang見習中のみけです。

オライリーの『Erlangプログラミング』は各章の最後にエクササイズがあって、

そのエクササイズの4-2を解いてみました。

内容


課題はN個のプロセスがリング上に形成されていて、

メッセージをM個伝達し、

M個伝達し終わったらプロセスを終了するというものです。





実行結果は下の通り。





なんか、もう少しプログラムの行数を減らせそうな気がする。


やってて覚えたこと


  • atomにプロセスをregister/2関数にて割り当てるとき、既に他のatomにプロセスが割り当てられている場合、エラーが発生する。
    • つまりひとつのプロセスはひとつのatomにしかregister/2関数で割り当てられない
  • whereis/1関数の戻り値はプロセスID
  • プロセスを強制終了する場合は、exit/2関数を用いる。引数はPid、終了する原因(atomなど)

うん


Erlangって型ないですねー

2013年4月30日火曜日

Erlangばっかりやっていますが

Erlang見習いミケです。

Erlangばっかりやっていますが、

本当はJavaのASTライブラリーを書きたいです。

書きたいですが、頭が混乱して、

自信喪失しているので、

Erlangで初歩的なことをして自信を回復しています。

以上、それだけです。

まあ、ErlangでWebアプリくらい作れるようになるといいなとおもいます。

2013年4月29日月曜日

Erlangでマージソート書いたら、なんか汚かったで御座る

Erlang見習中のみけです。

Erlangでマージソート書いたら、クイックソートの100倍は汚いコードになりました。

誰かツッコミください。












2013年4月25日木曜日

Erlangでプロセスたくさん使ってフィボナッチ数列を計算したら、too many processesとなっておこられたで御座る。

調子が悪いので

Erlangで初心者的なことをやって

自信を回復しようとしているみけです。



Erlangでのプロセス間通信


spawnという関数を用いて関数を実行すると、

その関数のプロセス識別子が取得出来ます。

そしてプロセス識別子に対して!演算子を用いることで、

プロセスに対してメッセージを送信することができます。


フィボナッチ数列の計算


ところで、Erlangでフィボナッチ数列を計算する関数は簡単に書けます。

-module(fib).
-export([fib/1]).

fib(N) when N < 2 -> 1;
fib(N) ->
    fib(N - 1) + fib(N - 2).

ところが、この関数はひとつのプロセスで実行するために、

値が大きくなると途端にパフォーマンスが低下します。

3> timer:tc(fib, fib, [10]).
{11,89}
4> timer:tc(fib, fib, [12]).
{24,233}
5> timer:tc(fib, fib, [14]).
{61,610}
6> timer:tc(fib, fib, [20]).
{1546,10946}

timer:tc関数の戻り値の一つ目の要素が実行時間(ms)です。

ガクガクって増えていっている様子がわかります。


そこで複数プロセスでフィボナッチ数列を計算する


そこで、fib:fib関数を少し修正して、

プロセス間通信する形で計算してみます。



では、試してみます。

3> timer:tc(fib, fib, [10]).
{2889,89}
4> timer:tc(fib, fib, [12]).
{5109,233}
5> timer:tc(fib, fib, [14]).
{5684,610}
6> timer:tc(fib, fib, [20]).
{132777,10946}


う〜んと、値が大きい割には、値の増え方が緩いですね。

では、40くらいだとどうなるでしょうか?

7> timer:tc(fib, fib, [10]).


結果が返ってきませんねー





あ、え、エラー…

too many processesだってw


というわけで


まあ、何が問題だったかというと、

所詮4コアしか積んでいないマシンで無数のプロセスを起動すると、

死ぬ

というわけですね。


まあ、当たり前と言っちゃ当たり前ですね。


さて、では、プロセス数を4より増やさないようにして

書いてみたのが次のやつになります。



関数fibはひとつのプロセスでやる奴。

関数cfibは二つのプロセスでやる奴。

関数ccfibは四つのプロセスでやる奴。


で、実際に時間を計測してみました。




だいたい、16〜20くらいで、複数プロセスの効果が現れていますね。






Erlangのリスト内包表記がすごい便利

Erlangのリスト内包表記がすごい便利です。

クイックソートも簡単に書けます。



これ、数学的には

(∀x; x ∈ P, Q(x, p))

って書いている感じなので、

読みやすいですし。




2013年4月24日水曜日

Erlangを少し勉強してみてる

少しだけErlangを勉強してます。

まだファイルIOとかできないし、

プロセス間の通信とかできないし、

並行処理とかできないし、

並列処理とかできないです。

重複する要素を含むリストの個数を数える関数を作ってみました。



実際に試してみました。



まだ、こんなレベル…