遅延評価
[id:lethevert:20051123:p5]
昨日の計算は、無駄な計算が多いと思ったので、コードをシンプルにして、もう一度再計算してみた。
module sine import StdEnv Start = doCalc 0.0 0 where calcs = getCalc where getCalc = [calc x \\ x <- [0..]] doCalc :: !Real Int -> Real doCalc res 10000000 = res doCalc res x = doCalc (res + (calcs!!i)) (x+1) //= doCalc (res + (calc i)) (x+1) where i = x rem 4 calc x = iter 10 sin ((toReal x) / 1000.0)
計算結果
計算結果を再利用した場合
$ time ./sine.exe 14999.850003575 real 0m0.921s user 0m0.020s sys 0m0.030s
毎回、再計算した場合
$ time ./sine.exe 14999.850003575 real 0m27.371s user 0m0.020s sys 0m0.030s
今度ははっきりと再利用の影響が分かる。
考察
昨日、再利用した方の計算時間が長かったのは、リストアクセス速度がボトルネックになっていたためのようだ。
ためしに、
i = x rem 4
を
i = 1000 + (x rem 4)
としてみると、3分たっても、計算が終わらない・・・