Ich schrieb zwei Funktionen zu überprüfen, ob eine Zahl in Haskell Primzahl ist:Primality Scheckzahlung, die Optimierung schien sich heraus Pessimierung in Haskell
prime :: Int -> Bool
prime 0 = False
prime 1 = False
prime 2 = True
prime n | even n = False
prime n = all (\x -> n `rem` x /= 0) [3,5..intSqrt]
where intSqrt = (floor . sqrt . fromIntegral) n
prime2 :: Int -> Bool
prime2 0 = False
prime2 1 = False
prime2 n = all (\x -> n `rem` x /= 0) [2..intSqrt]
where intSqrt = (floor . sqrt . fromIntegral) n
Die erste Version soll im Durchschnitt tun Hälfte der Berechnungen der der zweite, weil gerade Zahlen übersprungen werden, aber es stellt sich heraus, dass die zweite Version, die langsamer erscheint, fast 2x schneller ist! Ich schließe Terminalsitzungen wörtlich mit ein.
Prime 1 Version:
$ ghc -O2 prime.hs
[1 of 1] Compiling Main (prime.hs, prime.o)
Linking prime ...
$ time ./prime
142913828922
real 0m4.617s
user 0m4.572s
sys 0m0.040s
Jetzt benutze ich das Programm ändern Verwendung der Prime2 Version zu machen:
$ ghc -O2 prime.hs
[1 of 1] Compiling Main (prime.hs, prime.o)
Linking prime ...
$ time ./prime
142913828922
real 0m2.288s
user 0m2.268s
sys 0m0.020s
$
Der Code in main
ist einfach:
main :: IO()
main = print $ sum $ filter prime2 [1..2000000]
Warum ist die zweite Version schneller, wenn sie die doppelte Anzahl an Modolus hat?
Ich kann es nicht reproduzieren, 'prime' ist 2x schneller als' prime2' für mich (ghc-7.10.1) – Yuras
@Yuras Kompilieren Sie mit -O2? (Meine Version von GHC ist anders: 'Glasgow Haskell Compiler, Version 7.6.3, Stufe 2 gebootet von GHC Version 7.6.3' – Caridorc
Ja, ich kompiliere mit' -O2'. Unterschiedliche Compiler-Versionen können jedoch unterschiedliches Verhalten erklären. – Yuras