2015-05-09 7 views
9

Ho il seguente programma che prende un grande input (un elenco di estensioni/mappatura mime, un elenco di file) e restituisce i risultati riga per riga (il tipo mime per ogni file).Perché un programma dovrebbe essere più veloce in runghc o con profilazione?

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 

Il programma era piuttosto lento, quindi ho iniziato a profilarlo e ho ottenuto uno strano risultato.

quando si compila con

ghc --make -O2 coding.hs 

Il programma è molto lento. Tuttavia, lo -fprof-auto sembra accelerare tutto. Compilato con

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

rende velocissimo -prof da solo non ha alcun effetto.

Stranamente, è anche molto veloce quando viene eseguito con runghc coding.hs.

Non ho idea di quale direzione andare da lì. Qualcuno capisce cosa sta succedendo qui?

EDIT: dovrei ricordare che il mio ghc è 7.10.1.

+3

Probabilmente qualche ottimizzazione abilitata da '-O2' sta andando male, ma è bloccata dalle annotazioni di profilazione aggiunte da' -fprof-auto'. In particolare GHC potrebbe aver deciso che 'mimeMap' viene usato una sola volta e spostato' M.fromList' nel secondo ciclo. Prova a costruire con '-fno-state-hack'. –

+0

Non riesco a riprodurre il comportamento lento. Quanto sono grandi 'n' e' q' nella tua situazione? – Lynn

+2

[Questo ghc ticket] (https://ghc.haskell.org/trac/ghc/ticket/1957) riguarda anche il codice IO che gira più lentamente con le ottimizzazioni e si velocizza notevolmente compilando con '-fno-state -hack'come Reid Barton ha menzionato. C'è qualche discussione in più su questo [sulla mailing list] (http://comments.gmane.org/gmane.comp.lang.haskell.glasgow.user/13941). – Lynn

risposta

2

Per fornire una risposta completa alla domanda:

Come Reid Barton accennato, il problema sembra essere l'ottimizzazione trucco Stato infame, che inlines mimeMap in azione IO ripetuta, eseguendolo molto di più volte del necessario. -fno-state-hack disabilita l'ottimizzazione e risolve il problema. Un altro modo per risolvere il problema è forzare una valutazione rigorosa di `` mimeMap.

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

Tuttavia, sembra anche essere una regression in GHC 7.10, in cui -fno-state-hack non risolve il problema. Questo spiega perché non ha risolto il problema per me.

Grazie mille a tutti per le vostre risposte.

Problemi correlati