Betrachten Sie das folgende Spielzeugprogramm, das alle Kombinationen von Zeichensubstitutionen in einem Wort berechnet, wie es oft in Passwörtern verwendet wird.Warum verliert dieses Haskell-Programm Speicherplatz, wenn es mit Optimierungen kompiliert wird?
import Data.Char (isLower, toUpper)
variants :: String -> [String]
variants "" = [""]
variants (c:s) = [c':s' | c' <- subst c, s' <- variants s]
where subst 'a' = "[email protected]"
subst 'e' = "eE3"
subst 'i' = "iI1"
subst 'l' = "lL1"
subst 'o' = "oO0"
subst 's' = "sS$5"
subst 'z' = "zZ2"
subst x | isLower x = [x, toUpper x]
subst x = [x]
main :: IO()
main = putStrLn $ show $ length $ variants "redistributables"
ich kompilieren Sie es mit und ohne Optimierungen:
$ ghc -fforce-recomp -Wall Test.hs -o test0
[1 of 1] Compiling Main (Test.hs, Test.o)
Linking test0 ...
$ ghc -fforce-recomp -O -Wall Test.hs -o test1
[1 of 1] Compiling Main (Test.hs, Test.o)
Linking test1 ...
Jetzt test0
und test1
die gleiche Leistung erzeugen, aber test1
verwendet viel mehr Speicher und verbringt die meiste Zeit in der Garbage Collection:
$ ./test0 +RTS -s 2>&1 | grep total
2 MB total memory in use (0 MB lost due to fragmentation)
Productivity 93.2% of total user, 93.3% of total elapsed
$ ./test1 +RTS -s 2>&1 | grep total
188 MB total memory in use (0 MB lost due to fragmentation)
Productivity 15.0% of total user, 15.0% of total elapsed
Warum?
Ich benutze GHC 7.4.1; Ich sollte wahrscheinlich einen neueren Compiler verwenden, aber das ist es, was ich im Moment praktisch habe, und der Fehler liegt wahrscheinlich bei mir.
7.4 ist ziemlich alt an diesem Punkt, mindestens 7,8 verwenden, wenn nicht 7.10. Um dies zu beantworten, müssen Sie wahrscheinlich '-ddump-simpl' übergeben, um die Kernausgabe zu erhalten, und dann durchgehen, um genau herauszufinden, was der Unterschied ist. – bheklilr
@bheklilr Fertig, dass. Natürlich ist der generierte Core sehr unterschiedlich, aber es ist wirklich schwer für einen Haskell-Anfänger, sich zu entwirren, und bisher ist es mir nicht gelungen. –
und was passiert mit -O2 Flagge? –