在haskell中比在c中生成冰雹序列慢一个数量级

edw*_*rdw 6 haskell

在他的博客文章The Glasgow Haskell编译器和LLVM中,David Terei使用了一个生成冰雹序列来比较GHC性能与C的示例.我决定自己运行它,结果令人难以置信:GHC版本慢了一个多一级.代码是无辜的:

import Data.Word

collatzLen :: Int -> Word32 -> Int
collatzLen c 1 = c
collatzLen c n | n `mod` 2 == 0 = collatzLen (c+1) $ n `div` 2
               | otherwise      = collatzLen (c+1) $ 3*n+1

pmax x n = x `max` (collatzLen 1 n, n)

main = print . solve $ 1000000
    where solve xs = foldl pmax (1,1) [2..xs-1]
Run Code Online (Sandbox Code Playgroud)

除了代入foldlfoldl',我不认为我可以做任何事情来了.GHC版本在45秒内找到答案,无论我使用哪个后端,而C版仅使用1.5秒!

我的设置是Haskell平台2011.2.0.1(32位)+ OS X 10.6.6与gcc 4.2.1.大卫在他的帖子中使用了GHC 6.13.这是GHC 7.0.3的已知错误吗?或者我一定错过了一些非常明显的东西.

编辑:事实证明我确实错过了一些明显的东西.通过简单地使用-O2flag,ghc现在可以生成非常快的代码.

edw*_*rdw 6

我的问题是为什么GHC在这种特殊情况下产生了如此慢的代码.答案是使用优化标志,-O,-O2等.通过使用它,我看到了执行时间45+秒下降到0.6秒,80X〜改善.