2015-05-09 15 views
9

Mam następujący program, który pobiera duże dane wejściowe (lista mapowania rozszerzeń/mime, lista plików) i wyniki wyjściowe linia po linii (typ mime dla każdego pliku).Dlaczego program byłby szybszy w runghc lub z profilowaniem?

import System.IO 
import Control.Monad 
import qualified Data.Map as M 
import System.FilePath 
import Data.Char 

main :: IO() 
main = do 
    input_line <- getLine 
    let n = read input_line :: Int -- Number of elements which make up the association table. 
    input_line <- getLine 
    let q = read input_line :: Int -- Number Q of file names to be analyzed. 

    mimeMap <- fmap M.fromList $ replicateM n $ do 
     input_line <- getLine 
     let input = words input_line 
     let ext = input!!0 -- file extension 
     let mt = input!!1 -- MIME type. 
     return (map toLower ext, mt) 

    replicateM_ q $ do 
     fname <- getLine 
     let ext = map toLower . drop 1 . takeExtension $ fname 
      mime = M.findWithDefault "UNKNOWN" ext mimeMap 
     putStrLn mime 

Program był dość powolny, więc zacząłem go profilować i uzyskałem dziwny wynik.

Kiedy skompilowany z

ghc --make -O2 coding.hs 

program jest bardzo powolny. Jednak wydaje się, że -fprof-auto przyspiesza to wszystko. Kompilowany z

ghc --make -O2 coding.hs -prof -fprof-auto -fforce-recomp 

powoduje, że błyskawicznie się rozwija -prof sam nie ma wpływu.

Dziwnie, jest również bardzo szybki w połączeniu z runghc coding.hs.

Nie mam pojęcia, w którą stronę iść dalej. Czy ktoś rozumie, co się tutaj dzieje?

EDYCJA: Powinienem wspomnieć, że moja ghc to 7.10.1.

+3

Prawdopodobnie część optymalizacji włączonej przez "-O2" jest błędna, ale jest blokowana przez adnotacje profilowania dodane przez '-fprof-auto'. W szczególności GHC mógł zdecydować, że 'mimeMap' jest używane tylko raz i przeniesione' M.fromList' do drugiej pętli. Spróbuj budować z '-fno-state-hack'. –

+0

Nie mogę odtworzyć powolnego zachowania. Jak duże są 'n' i' q' w twojej sytuacji? – Lynn

+2

[Ten bilet ghc] (https://ghc.haskell.org/trac/ghc/ticket/1957) to także kod IO, który działa wolniej z włączonymi optymalizacjami i znacznie przyspiesza, kompilując się przy pomocy '-fno-state - jak wspomina Reid Barton. Dyskusja na ten temat odbywa się na [liście mailingowej] (http://comments.gmane.org/gmane.comp.lang.haskell.glasgow.user/13941). – Lynn

Odpowiedz

2

Aby zapewnić pełną odpowiedź na pytanie:

Jak wspomniano Reid Barton, problem wydaje się być niesławny optymalizacja Hack stan, który inlines mimeMap do wielokrotnego działania IO, wykonując go znacznie więcej razy niż jest to konieczne. -fno-state-hack wyłącza tę optymalizację i rozwiązuje problem. Innym sposobem rozwiązania problemu jest wymuszenie ścisłej oceny `` mimeMap.

!mimeMap <- fmap M.fromList $ replicateM n [...] 

Jednakże istnieją również wydaje się być regression in GHC 7.10, w którym -fno-state-hack nie rozwiązuje problemu. To tłumaczy, dlaczego mnie to nie naprawiło.

Dziękuję wszystkim za odpowiedzi.

Powiązane problemy