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 をよく読もう!と思った