Zajmuję się problemami w Project Euler jako sposobie uczenia się Haskella, i uważam, że moje programy są dużo wolniejsze niż porównywalna wersja C, nawet jeśli zostały skompilowane. Co mogę zrobić, aby przyspieszyć swoje programy Haskell?Jak poprawić wydajność tego programu Haskell?
Na przykład, mój siłowych rozwiązanie Problem 14 jest:
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
które trwa około 220 sekund, podczas gdy "równoważne" brute-force wersja C trwa tylko 1,2 sekundy.
#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;
}
Co robię źle? Czy może jestem naiwny sądzić, że Haskell może nawet zbliżyć się do prędkości C?
(Kompiluję wersję C z gcc -O2, a wersją Haskella z ghc --make -O).
Twoja "unsigned long" może mieć długość tylko 32-bitów. Dla uczciwego porównania użyj 'unsigned long long' lub' uint64_t'. – kennytm
@KennyTM - punkt fair - testowałem na 32-bitowym Ubuntu, gdzie długa jest 64-bitowa. – stusmith
@stusmith: Rozumiem. W porządku. – kennytm