lists:map/2 のかわりにリスト内包表記を使う

これと・・・

lists:map(fun (X) -> X*2 end, lists:seq(1, 10)).

これは・・・

[fun (X) -> X*2 end(X) || X <- lists:seq(1, 10)].

同じ結果になる。

下記のような適当な実行時間を計測する module を作って・・・

-module(bench).
-export([mark/1]).

mark(Fun) ->
  lists:foreach(fun statistics/1, [runtime, wall_clock]),
  Fun(),
  io:format(
    "~p (~p) msec~n",
    lists:map(fun (Type) ->
      {_, T} = statistics(Type),
      T
    end, [runtime, wall_clock])
  ).

実際に速度を調べてみる。(OS:Mac OSX 10.4.10 / CPU:PowerPC G5 1.6GHz / MEM:1.25GB)

% erl
1> bench:mark(fun () -> lists:map(fun (X) -> X*2 end, lists:seq(1, 9999)) end).
70 (95) msec
ok
2> bench:mark(fun () -> [fun (X) -> X*2 end(X) || X <- lists:seq(1, 9999)] end).
810 (935) msec
ok

リスト内包表記遅い!

訂正

上記の書き方だと、毎回、無名関数を生成する事になるから、リスト内包表記の方が不利だと気がつく。

% erl
1> Calc = fun (X) -> X*2 end.
#Fun<erl_eval.6.72228031>
2> bench:mark(fun () -> [Calc(X) || X <- lists:seq(1, 9999)] end).
140 (205) msec
ok

極端に遅いわけじゃないみたい。

まずは、Efficiency Guide をよく読もう!と思った