Ich erkannte, dass die neueste Version von GHC (7.10.3) erheblich langsamer Code als eine ältere Version produziert. Meine aktuelle Version ab sofort:GHC 7.10 generiert langsameren Code als ältere Versionen
$ ghc --version
The Glorious Glasgow Haskell Compilation System, version 7.10.3
Ich habe auch zwei andere alte Versionen auf meinem lokalen Rechner installiert.
My Testcode wird entnommen aus here (der collatz1.hs
code):
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]
Kompilieren mit GHC 7,4, 7,6 und 7,10 ergibt die folgenden Zeiten:
$ ~/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
Wir können sagen, dass es keinen Zweifel gibt, dass die neueste Version von GHC schlechteren Code als die älteren zwei Versionen produziert. Ich kann nicht die gleiche Effizienz wie der Blog reproduzieren, aber wahrscheinlich, weil ich kein LLVM habe und nicht die genaue Version, die der Autor verwendet hat. Trotzdem glaube ich, dass die Schlussfolgerung offensichtlich ist.
Meine Frage ist im Allgemeinen, warum dies passieren könnte? Irgendwie wird GHC schlechter als früher. Und speziell, wenn ich untersuchen will, wie soll ich mich selbst anfangen lassen?
Das ist eine Geschwindigkeitsregression und sollte als ein Problem gemeldet werden. Auf diese Weise können die Autoren des Compilers das Problem überprüfen und/oder Ihnen sagen, woher die Regression stammt.Wenn Sie mit GHC nicht vertraut sind, können Sie sich zunächst den erzeugten Kern nach der Vereinfachung ansehen, z. '-ddump-simpl 'und auf Unterschiede prüfen. – Zeta
@ Zeta klingt gut. Ich werde diesen Bericht erhalten – HuStmpHrrr
Hatte einen schnellen Blick, sie scheinen sich hauptsächlich darin zu unterscheiden, ob Funktionen inline oder floated sind, aber ich bin mir nicht sicher darüber. Für diejenigen, die stack verwenden: 'stack --install-ghc --resolver = ghc-7.8 ghc - Test.hs -O2 -ddump-simpl-suppress-all-effekt-rekomp> 7.8.dump; Stapel --install-ghc --resolver = ghc-7.10 ghc - Test.hs -O2 -ddump-simpl-suppress-all-effekt-rekomp> 7.10.dump; vimdiff 7.8.dump 7.10.dump' (Ersetzen Sie Vimdiff durch Ihren bevorzugten Diff-Befehl). Scheint wie der Unterschied ist während der Optimierung, obwohl. – Zeta