Tôi đang làm việc thông qua các vấn đề trong Project Euler như một cách để học Haskell và tôi thấy rằng các chương trình của tôi chậm hơn rất nhiều so với phiên bản C so sánh, ngay cả khi được biên dịch. Tôi có thể làm gì để tăng tốc các chương trình Haskell của mình?Làm cách nào để cải thiện hiệu suất của chương trình Haskell này?
Ví dụ, giải pháp brute-force của tôi để Problem 14 là:
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
nào mất khoảng 220 giây, trong khi một phiên bản "tương đương" brute-force C chỉ mất 1,2 giây.
#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;
}
Tôi đang làm gì sai? Hay tôi ngây thơ khi nghĩ rằng Haskell thậm chí có thể tiếp cận tốc độ của C?
(Tôi đang biên dịch phiên bản C với gcc -O2 và phiên bản Haskell có ghc --make -O).
'Không ký dài' của bạn có thể chỉ dài 32 bit. Để so sánh công bằng, hãy sử dụng 'unsigned long long' hoặc 'uint64_t'. – kennytm
@KennyTM - điểm công bằng - Tôi đã thử nghiệm trên Ubuntu 32 bit, nơi có thời gian dài là 64 bit. – stusmith
@stusmith: Tôi hiểu rồi. Tốt rồi. – kennytm