Кто-нибудь знает, как сделать этот код Haskell более быстрым? Я делаю Project Euler #14. Этого код работает в 4.029 секундах:Создание кода Haskell быстрее
collatz :: Int -> Int64 -> Int
collatz c 1 = c
collatz c k
| even k = collatz (c+1) (k `div` 2)
| otherwise = collatz (c+1) (3*k + 1)
main = do
print $ maximum (map (\i -> (collatz 1 i, i)) [1..1000000])
Memoizing функция Коллатец фактически увеличивает время работы, так что я не делал никакого запоминания. Аналогичный код С работает в 0,239 секунд:
int main(int argc, char *argv[])
{
int maxlength = 0;
int maxstart = 1;
for (int i = 1; i <= 1000000; i++) {
unsigned long k = i;
int length = 1;
while (k > 1) {
length += 1;
if (k % 2 == 0)
k = k/2;
else
k = 3*k + 1;
}
if (length > maxlength) {
maxlength = length;
maxstart = i;
}
}
printf("%d, %d\n", maxlength, maxstart);
return 0;
}
Код Хаскел собран с GHC -O3 и код C собран с GCC -std = C99 -O3.
Аннотации Strictness - это первая вещь, за которой следует 'shiftR x 1' вместо' div x 2' (да, некоторые ключевые оптимизации все еще отсутствуют). Это доставляет вам поразительное расстояние от C. –
Эта конкретная проблема Эйлера проекта породила целую кучу подобных вопросов производительности в прошлом. Взгляните на [этот поиск] (http://stackoverflow.com/search?q= [haskell] + collatz) за кучу советов. [Этот вариант] (http://stackoverflow.com/questions/13669134/c-vs-haskell-collatz-conjecture-speed-comparison/13669277#13669277) может иметь особое значение. –
У вас есть LLVM? он работает на 1,3 секунды на моей машине с -O2 -fllvm. –