haskell - 为什么这个 Haskell 表达式这么慢?

标签 haskell optimization

我正在研究 Project Euler Problem 14。这是我的解决方案。

import Data.List

collatzLength :: Int->Int
collatzLength 1 = 1
collatzLength n | odd n = 1 + collatzLength (3 * n + 1)
                | even n = 1 + collatzLength (n `quot` 2)

maxTuple :: (Int, Int)->(Int, Int)->Ordering
maxTuple (x1, x2) (y1, y2)  | x1 > y1 = GT
                | x1 < y1 = LT
                | otherwise = EQ

我正在运行以下 GHCi
maximumBy maxTuple [(collatzLength x, x) | x <- [1..1000000]]

我知道,如果 Haskell 严格评估,那么这个时间将类似于 O(n3)。不过,由于 Haskell 的评估是惰性的,看起来这应该是 n 的某个常数倍数。这已经运行了将近一个小时。显得非常不合理。有谁知道为什么?

最佳答案

您假设 collatzLength函数将被内存。 Haskell 不做自动内存。你需要自己做。这是一个使用 data-memocombinators 的示例包裹。

import Data.List
import Data.Ord
import qualified Data.MemoCombinators as Memo

collatzLength :: Integer -> Integer
collatzLength = Memo.arrayRange (1,1000000) collatzLength'
  where
    collatzLength' 1 = 1
    collatzLength' n | odd n  = 1 + collatzLength (3 * n + 1)
                     | even n = 1 + collatzLength (n `quot` 2)

main = print $ foldl1' max $ [(collatzLength n, n) | n <- [1..1000000]]

使用 -O2 编译时运行大约 1 秒。 .

关于haskell - 为什么这个 Haskell 表达式这么慢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7134669/

相关文章:

haskell - 如何使用 GHCi :set args on quoted strings that include functions

haskell - 全局 Stack config.yaml 中的标志

haskell - 什么是单子(monad)?

java - 拥有大量小方法是否有助于 JIT 编译器优化?

c++ - 禁用优化后 quick-bench.com 上的基准测试速度要快得多

java - 通过查看内置类的编译器代码来编写优化代码的示例

python - 如何使用Python跳过二进制标准输入的n行?

list - 将map与具有多个参数的函数一起使用

haskell - 类似的 Haskell 列表推导式具有不同的结果

c++ - -fno-omit-frame-pointer 没有优化