我已经实现了一个代码,该代码在给定基本情况和线性递归关系系数的情况下生成无限序列。
import Data.List
linearRecurrence coef base | n /= (length base) = []
| otherwise = base ++ map (sum . (zipWith (*) coef)) (map (take n) (tails a))
where a = linearRecurrence coef base
n = (length coef)
这是Fibonacci数字的实现。 fibs = 0:1 :( zipWith(+)fibs(tail fibs))
很容易看出
linearRecurrence [1,1] [0,1] = fibs
但是,计算fibs!!2000
的时间为0.001秒,(linearRecurrence [1,1] [0,1])!!2000
的时间约为1秒。速度的巨大差异来自哪里?我已经使一些功能严格。例如,(sum . (zipWith (*) coef))
被(id $! (sum . (zipWith (*) coef)))
取代,但没有帮助。
答案 0 :(得分:10)
您反复计算linearRecurrence coef base
。利用共享,如:
linearRecurrence coef base | n /= (length base) = []
| otherwise = a
where a = base ++ map (sum . (zipWith (*) coef)) (map (take n) (tails a))
n = (length coef)
请注意a
的分享。
现在你得到:
*Main> :set +s
*Main> fibs!!2000
422469...
(0.02 secs, 2203424 bytes)
*Main> (linearRecurrence [1,1] [0,1])!!2000
422469...
(0.02 secs, 5879684 bytes)