lists:foreach、 関数渡し

cooldaemon さんが Erlang の lists モジュールの性能検証してくれている。どんどんコードを書いて進んでいくところは見習いたいが、なかなか手がついていかんなぁ。

ひとつ、lists:foreach について、気になった。

lists モジュール、自前の関数、リスト内包表記の速度比較 - cooldaemonの備忘録
foreach

末尾再帰できなくても自前の関数の方が早い・・・コードの書き方が悪いのかな?

lists:foreach/2 を使ったからといって、可読性が劇的に上がるわけでもないので、lists:foreach/2 は使うの止めよう。

http://d.hatena.ne.jp/cooldaemon/20080820/1219209698

lists:foreach を見てみると、このようになっている。

foreach(F, [Hd|Tail]) ->
    F(Hd),
    foreach(F, Tail);
foreach(F, []) when is_function(F, 1) -> ok.

最初に、一番当たるだろう末尾再帰がきて、なんでか分からんけど、空リストのときには、is_function でガードしている。
このコードで、自前末尾再帰と差が出るのが不思議だったので、cooldaemon さんのコードにひとつテストを足してみる。 # gist つかいやすいね
http://gist.github.com/6484

自前末尾再帰の foreach 相当のコードで、関数を渡す版を付けた。すると、当然ながら(?)、 lists:foreach と同じ程度の数字が出てくる。ということは、lists:foreach というよりは、関数を渡す、または、渡された関数の実行という部分で、なんかしらオーバーヘッドがある、と思うほうが良さそう。