fib1 n =
case n of
0 -> 1
1 -> 1
x -> (fib1 (x-1)) + (fib1 (x-2))
fib2 n = fibArr !! n where
fibArr = 1:1:[a + b | (a, b) <- zip fibArr (tail fibArr)]
它们在数学上非常相似,但`fib2`使用列表表示法来记忆化其中间结果,而`fib1`具有显式递归。 尽管可以在`fib1`中缓存中间结果,但即使对于`fib1 25`,执行时间也成为问题,表明始终评估递归步骤。 引用透明是否对Haskell的性能有所贡献?我如何事先知道它会或不会?这只是我担心的问题的一个例子。 我想听听关于克服推理懒执行函数式编程语言性能难度的任何想法。总之,我接受3lectrologos的答案,因为他指出在Haskell中你无需考虑语言的性能,而更应该关注编译器的优化,这似乎比我熟悉的任何其他语言都更重要。 我倾向于说编译器的重要性是区分推理懒惰的函数式语言的性能与推理任何其他类型的性能的因素。此外,任何看到此问题的人可能希望查看Johan Tibell的高性能Haskell演讲幻灯片。
let f x = .... in f 15 + f 15
这样的东西时才会出现。由于您没有给f 15
命名,它会被计算两次还是一次?答案是“取决于情况”和“可能会计算两次”,因为 GHC 可以检测到这种重复,但它通常无法估计共享结果是否是一个好主意,因为有些情况下这是一个非常糟糕的主意,甚至会将程序从 O(1) 的空间使用更改为 O(n)! - Jedai