Я понял, что последняя версия GHC (7.10.3) производит значительно более медленный код, чем более старая версия. Текущая версия на данный момент:
$ ghc --version
The Glorious Glasgow Haskell Compilation System, version 7.10.3
У меня есть еще две старые версии, установленные на моей локальной машине.
Мой тестовый код взят из здесь (код collatz1.hs
):
import Data.Word
import Data.List
import System.Environment
collatzNext :: Word32 -> Word32
collatzNext a = (if even a then a else 3*a+1) `div` 2
-- new code
collatzLen :: Word32 -> Int
collatzLen a0 = lenIterWhile collatzNext (/= 1) a0
lenIterWhile :: (a -> a) -> (a -> Bool) -> a -> Int
lenIterWhile next notDone start = len start 0 where
len n m = if notDone n
then len (next n) (m+1)
else m
-- End of new code
main = do
[a0] <- getArgs
let max_a0 = (read a0)::Word32
print $ maximum $ map (\a0 -> (collatzLen a0, a0)) [1..max_a0]
Компиляция с GHC 7.4, 7.6 и 7.10 дает следующие моменты:
$ ~/Tools/ghc-7.4.2/bin/ghc -O2 Test.hs
[1 of 1] Compiling Main ( Test.hs, Test.o )
Linking Test ...
$ time ./Test 1000000
(329,837799)
real 0m1.879s
user 0m1.876s
sys 0m0.000s
$ ~/Tools/ghc-7.6.1/bin/ghc -O2 Test.hs
[1 of 1] Compiling Main ( Test.hs, Test.o )
Linking Test ...
$ time ./Test 1000000
(329,837799)
real 0m1.901s
user 0m1.896s
sys 0m0.000s
$ ~/Tools/ghc/bin/ghc -O2 Test.hs
[1 of 1] Compiling Main ( Test.hs, Test.o )
Linking Test ...
$ time ./Test 1000000
(329,837799)
real 0m10.562s
user 0m10.528s
sys 0m0.036s
Мы можем сказать, что нет сомнений в том, что последняя версия GHC создает худший код, чем предыдущие версии. Я не могу воспроизвести такую же эффективность, как блог, хотя, вероятно, потому, что у меня нет LLVM, и у Idon нет точной версии, которую использовал автор. Но все же, я считаю, что вывод очевиден.
Мой вопрос, в общем, почему это может произойти? Каким-то образом GHC становится хуже, чем раньше. И конкретно, если я хочу исследовать, как я должен начать себя?