Otimização do GHC: conjectura de Collatz
Eu escrevi código para oDesafio do Projeto Euler 14, em ambosHaskell eC ++ (links ideone). Ambos lembram-se de quaisquer cálculos feitos anteriormente em uma matriz.
Usandoghc -O2
eg++ -O3
respectivamente, o C ++ é executado 10-15 vezes mais rápido que a versão Haskell.
Embora eu entenda que a versão Haskell pode ser mais lenta, e que Haskell é uma linguagem melhor para escrever, seria bom saber algumas mudanças de código que eu posso fazer na versão Haskell para fazê-lo rodar mais rápido (idealmente dentro de um fator de 2 ou 3 da versão C ++)?
O código do Haskell está aqui:
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)
Editar:
Eu também fiz uma versão usando matrizes mutáveis sem caixa. Ainda é 5 vezes mais lento que a versão C ++, mas uma melhoria significativa. O código está no ideoneAqui.
Eu gostaria de conhecer melhorias na versão do array mutável que o aproxima da versão C ++.