Haskell缓存纯函数调用的结果,这也是纯和非纯行为分离的原因之一。然而,下面这个函数应该在n为50
时以O(n)运行,但实际上运行非常慢:
lucas 1 = 1
lucas 2 = 3
lucas n = lucas (n-1) + lucas (n-2)
map (lucas) [1..50]
前三十个数可以在不到一秒钟内计算出来,然后第31个数需要大约半秒钟左右,32个需要一整秒,33个需要几秒钟,34个需要6秒,35个需要11秒,36个需要17秒...
为什么这个函数如此缓慢?如果 GHC 交互式运行时正在缓存结果,则每次调用 "lucas" 应该只涉及对前两个缓存项的求和。通过一次加法操作找到第3项,再通过一次加法操作找到第4项,再通过一次加法操作找到第5项,因此在考虑缓存的情况下,仅需48次加法即可找到第50项。该函数不应该花费任何接近一秒钟的时间来找到至少前几千个数,为什么性能如此糟糕?
我已经等了半个多小时了,以便计算 "lucas 500"。