Haskell中的线性递归关系实现太慢了

时间:2011-11-30 08:40:16

标签: haskell

我已经实现了一个代码,该代码在给定基本情况和线性递归关系系数的情况下生成无限序列。

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)))取代,但没有帮助。

1 个答案:

答案 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)