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.
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. –
@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
@EDwardw, jakie jest twoje pytanie? – eternalmatt