Sto lavorando ai problemi in Project Euler come metodo per apprendere Haskell, e trovo che i miei programmi siano molto più lenti di una versione C paragonabile, anche quando sono compilati. Cosa posso fare per velocizzare i miei programmi Haskell?Come migliorare le prestazioni di questo programma Haskell?
Per esempio, la mia soluzione a forza bruta per Problem 14 è:
import Data.Int
import Data.Ord
import Data.List
searchTo = 1000000
nextNumber :: Int64 -> Int64
nextNumber n
| even n = n `div` 2
| otherwise = 3 * n + 1
sequenceLength :: Int64 -> Int
sequenceLength 1 = 1
sequenceLength n = 1 + (sequenceLength next)
where next = nextNumber n
longestSequence = maximumBy (comparing sequenceLength) [1..searchTo]
main = putStrLn $ show $ longestSequence
che in circa 220 secondi, mentre una versione "equivalente" a forza bruta C richiede solo 1,2 secondi.
#include <stdio.h>
int main(int argc, char **argv)
{
int longest = 0;
int terms = 0;
int i;
unsigned long j;
for (i = 1; i <= 1000000; i++)
{
j = i;
int this_terms = 1;
while (j != 1)
{
this_terms++;
if (this_terms > terms)
{
terms = this_terms;
longest = i;
}
if (j % 2 == 0)
j = j/2;
else
j = 3 * j + 1;
}
}
printf("%d\n", longest);
return 0;
}
Cosa sto facendo male? O sono ingenuo pensare che Haskell potrebbe persino avvicinarsi alla velocità di C?
(Sto compilando la versione C con gcc -O2 e la versione Haskell con ghc --make -O).
Il tuo 'unsigned long' può essere lungo solo 32 bit. Per un confronto equo, usa un 'long long unsigned' o 'uint64_t'. – kennytm
@KennyTM - equo punto - stavo testando su Ubuntu a 32 bit dove a lungo capita di essere a 64-bit. – stusmith
@stusmith: capisco. Va bene allora. – kennytm