在他的博客文章The Glasgow Haskell Compiler and 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]
除了用foldl
代替foldl'
,我认为我无法做任何事情。 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的已知错误吗?或者我一定错过了一些非常明显的事情。
编辑:事实证明我确实错过了一些明显的东西。通过简单地使用-O2
标志,ghc现在可以生成非常快的代码。
答案 0 :(得分:6)
我的问题是为什么GHC在这种特殊情况下产生了如此慢的代码。答案是使用优化标志-O
,-O2
等。通过使用它,我看到执行时间从45秒减少到0.6秒,改善了80倍。