我有以下的,用于在Haskell计算第n个斐波纳契数经常被引用的代码:非pointfree风格基本上是慢
fibonacci :: Int -> Integer
fibonacci = (map fib [0..] !!)
where fib 0 = 0
fib 1 = 1
fib n = fibonacci (n-2) + fibonacci (n-1)
利用这一点,我能做到的呼叫如:
ghci> fibonacci 1000
并收到几乎即时的答案。
然而,如果我修改上面的代码,以便它不是在pointfree风格,即
fibonacci :: Int -> Integer
fibonacci x = (map fib [0..] !!) x
where fib 0 = 0
fib 1 = 1
fib n = fibonacci (n-2) + fibonacci (n-1)
它是慢得多。致电如
ghci> fibonacci 1000
挂起。
我的理解是上述两段代码是等价的,但GHCi有所不同。有没有人有这种行为的解释?
第一个定义更像'fibonacci = let k = map fib [0 ..] in \ x - > k !! x'。它可能共享结果列表,而不是每次重新计算结果。 – melpomene
嗯,所以我很满意,这是“共享”(记忆),使第一个超级快。但为什么对于第二个呢? – MadMonty
您正在GHCI中运行您的代码,没有进行优化。试着用'-O2'编译这两个函数,看看GHC是否足够聪明,可以为你解决问题。 – user2407038