Оптимизация GHC: гипотеза Коллатца
Я написал код дляProject Euler's Challenge 14, в обоихHaskell а такжеC ++ (идеально ссылки). Они оба помнят любые вычисления, которые они ранее делали в массиве.
С помощьюghc -O2
а такжеg++ -O3
соответственно C ++ работает в 10-15 раз быстрее, чем версия на Haskell.
Хотя я понимаю, что версия на Haskell может работать медленнее, и что Haskell является более приятным языком для написания, было бы неплохо узнать некоторые изменения кода, которые я могу внести в версию на Haskell, чтобы она работала быстрее (в идеале с коэффициентом 2 или 3 версии C ++)?
Код на 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:
Теперь я также сделал версию, использующую неупакованные изменяемые массивы. Это все еще в 5 раз медленнее, чем версия C ++, но это значительное улучшение. Код на IdeoneВот.
Я хотел бы знать улучшения в версии изменяемого массива, которые приближают ее к версии C ++.