2011-07-13 8 views
6

W swoim wpisie na blogu The Glasgow Haskell Compiler and LLVM, David Terei użył przykładu, który wygenerował sekwencję gradową, aby porównać wydajność GHC z C. Zdecydowałem się uruchomić to samo, a wynik jest niewiarygodny: GHC wersja jest wolniejsza o więcej niż jeden rozmiar. Kod jest dość niewinnie:Jedna wielkość wolniej generująca sekwencję gradową w haskell niż w c

import Data.Word 

collatzLen :: Int -> Word32 -> Int 
collatzLen c 1 = c 
collatzLen c n | n `mod` 2 == 0 = collatzLen (c+1) $ n `div` 2 
       | otherwise  = collatzLen (c+1) $ 3*n+1 

pmax x n = x `max` (collatzLen 1 n, n) 

main = print . solve $ 1000000 
    where solve xs = foldl pmax (1,1) [2..xs-1] 

wyjątkiem zamiany foldl z foldl', nie sądzę, mogę zrobić coś do niego. Wersja GHC znajduje odpowiedź w 45 sekund, bez względu na to, z jakiego zaplecza korzystam, podczas gdy wersja C używa tylko 1,5 sekundy!

Moja konfiguracja to platforma Haskell 2011.2.0.1 (32bit) + OS X 10.6.6 vs. gcc 4.2.1. David użył GHC 6.13 w swoim poście. Czy jest to znany błąd GHC 7.0.3? Albo musiałem przegapić coś bardzo oczywistego.

EDYCJA: Okazuje się, że przegapiłem coś oczywistego. Używając po prostu flagi -O2, ghc wytwarza teraz bardzo szybki kod.

+4

z których flag kompilacji używasz? Dla mnie ten kod jest wykonywany w 4s po kompilacji przy użyciu 'ghc-7.0.4 -O2'. "-O" jest tylko nieznacznie wolniejsze. –

+3

@John L, użyłem '' '--make -fforce-recomp -fllvm''''. Używając "-O2", jak zasugerowałeś, ghc jest na równi z gcc. Dzięki. – edwardw

+0

@EDwardw, jakie jest twoje pytanie? – eternalmatt

Odpowiedz

6

Moje pytanie brzmiało, dlaczego GHC wytworzył tak powolny kod w tym konkretnym przypadku. Odpowiedzią jest użycie flagi optymalizacji, -O, -O2 itd. Za jej pomocą czas wykonywania spadł z 45+ sekund do 0.6 sekundy, ~ 80x poprawa.

Powiązane problemy