Ich habe Code für die Project Euler's Challenge 14, in Haskell und C++ (Ideone Links) geschrieben. Beide erinnern sich an Berechnungen, die sie zuvor in einem Array durchgeführt haben.GHC Optimierung: Collatz Vermutung
Mit ghc -O2
bzw. g++ -O3
läuft das C++ 10-15 Mal schneller als die Haskell-Version.
Während ich verstehe, dass die Haskell - Version möglicherweise langsamer läuft, und dass Haskell eine bessere Sprache zum Schreiben ist, wäre es schön, einige Codeänderungen zu kennen, die ich machen kann, um die Haskell - Version schneller laufen zu lassen (idealerweise innerhalb einer Faktor 2 oder 3 der C++ Version)?
Haskell-Code ist hier:
import Data.Array
import Data.Word
import Data.List
collatz_array =
let
upperbound = 1000000
a = array (1, upperbound) [(i :: Word64, f i :: Int) | i <- [1..upperbound]]
f i = i `seq`
let
check_f i = i `seq` if i <= upperbound then a ! i else f i
in
if (i == 1) then 0 else (check_f ((if (even i) then i else 3 * i + 1) `div` 2)) + 1
in a
main =
putStrLn $ show $
foldl1' (\(x1,x2) (y1,y2) -> if (x2 >= y2) then (x1, x2) else (y1, y2)) $! (assocs collatz_array)
Edit:
Ich habe jetzt getan auch eine Version unboxed änderbare Arrays. Es ist immer noch 5 mal langsamer als die C++ - Version, aber eine deutliche Verbesserung. Der Code ist auf Ideone here.
Ich würde gerne Verbesserungen an der veränderbaren Array-Version wissen, die es näher an der C++ - Version bringen.
Nur FYI, Compiling mit '-fllvm' verbessert die Leistung um ~ 10% auf meinem Rechner. –
Ihre 'seq' machen keinen Unterschied; Beide Funktionen sind in "i" streng. Früher war GHC bei 64-Bit-Arithmetik auf 32-Bit-Plattformen ziemlich schlecht, aber ich weiß nicht, welche Plattform Sie verwenden. – augustss
Verwenden Sie nicht 'div', verwenden' quot'. – augustss