Я написал код для Project Euler Challenge 14, в Haskell и С++ (ideone links). Они оба помнят любые вычисления, которые они ранее делали в массиве.
Используя ghc -O2
и g++ -O3
соответственно, С++ работает в 10-15 раз быстрее, чем версия Haskell.
Пока я понимаю, что версия Haskell может работать медленнее, и что Haskell - более удобный язык для записи, было бы неплохо узнать некоторые изменения кода, которые я могу сделать для версии Haskell, чтобы заставить ее работать быстрее (в идеале в пределах фактора 2 или 3 версии С++)?
Код Haskell находится здесь:
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:
Я также сделал версию с использованием unboxed изменяемых массивов. Он по-прежнему в 5 раз медленнее, чем версия С++, но значительно улучшилась. Код находится на ideone здесь.
Я хотел бы знать улучшения в версии mutable array, которые приближают ее к версии С++.