遅延評価
誰かが、遅延評価が嬉しいと思ったことはないと書いていたような気がしたが、そんなこともないのではないかと思って、実験してみることにした。
遅延評価を上手く使うと、時間のかかる計算を、結果の再利用をしてリソースの節約をするようなコードが簡単に書けるはず。
サンプル
module sine import StdEnv Start = doCalc 0.0 1 where // 計算の再利用のために必要な追加コード // calcs = getCalc where getCalc = [calc x \\ x <- [0..]] // ==================================== // doCalc :: !Real Int -> Real doCalc res 9999999 = res doCalc res x = doCalc (res + (calcs!!i)) (x+1) //= doCalc (res + (calc i)) (x+1) where i = abs (((~3*x*x+16*x+350) rem 4) * 23) calc x = (sinh o tan o sin o cos o acos o atan o cosh o asin) ((toReal x) / 1000.0)
calcという計算を、9999999回繰り返して、その合計を求めるという計算。
で、コメントアウトした方が、計算の再利用をしていないコード。
再利用をするために必要なコードは、わずか4行。
実行時間
再利用した場合
$ time ./sine.exe 9633764.15158449 real 0m7.851s user 0m0.020s sys 0m0.040s
再利用しない場合
$ time ./sine.exe 9633764.15158449 real 0m33.162s user 0m0.010s sys 0m0.060s
まあ、この結果はあたりまえですけど、再利用をする側は、もっと速いと思っていたんだけど。