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日火曜日

企業が求めるストレスに強い人材像に関する矛盾

ストレス耐性のないみけです。

デスマとかになると、

メンバーが苛ついて、

攻撃的になりますね。


さて、企業が求めるストレスに強い人材とかいう

馬鹿げた人物像がありますが、



あれ、


苛ついたメンバーが攻撃的になるのは

おkで、

その苛ついたメンバーの攻撃対象になった人が、

鬱とか精神失調になった時の、

攻撃対象になった人がストレスに弱い人材と

なっているみたいですね。


おかしくないですか?


ストレスを抱えているのは、

攻撃的な人材も、攻撃を受ける人材も同じなのに、

それが攻撃的に出る人材が

ストレス耐性があるとでも言うんでしょうか?


馬鹿げてますね。


攻撃的になる人材のほうが

ストレス耐性が弱いですよ。


そういう人間は攻撃することで、

ストレスから逃れているので、

まあ生き残れます。

でも、

攻撃対象になった人間が

ストレス耐性がないと断定するのは

おかしいですよね。


攻撃的になっている人間が

ストレス耐性がないというのを

見逃していると思います。


だから、企業はストレス耐性がある人間といった時に、

ストレスが掛かった状態で

攻撃的になる人間を採用してはいけないわけです。


人間、ストレス抱えた状態で、

味方であるはずのメンバーから攻撃されれば、

逃げ場はなくなります。


そんなの、ストレス耐性があろうが

なかろうが、追い詰められるのは当たり前です。


だから、ストレスで攻撃的になる人間、

そういう人間を早期発見して、

解雇するなり、

プロジェクトから外すなりしたほうが

企業として優秀な人材を失わなくて済むし、

社会にとっても有益なはずです。


結論


ストレスで攻撃的になる人間は

死すべき、そして社会から抹殺されるべき


以上。





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とかできないし、

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

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

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

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



実際に試してみました。



まだ、こんなレベル…