2015-05-13 16 views
12

Sto cercando opportunità di ottimizzazione nel mio programma Haskell compilando con -prof, ma non so come interpretare i centri di costo che contengono ellissi. Cosa sono filter.(...) e jankRoulette.select.(...)?Cosa significa. (...) in un rapporto .prof significa?

COST CENTRE    MODULE      %time %alloc 

filter.(...)    Forest      46.5 22.3 
set-union     Forest      22.5 4.1 
cache-lookup    Forest      16.0 0.1 
removeMany     MultiMapSet     3.7 1.9 
insertMany     MultiMapSet     3.3 1.8 
jankRoulette.select.(...) Forest      1.4 15.2 

ho generato che con: $ ghc --make -rtsopts -prof -auto-all main.hs && ./main +RTS -p && cat main.prof

La funzione filter ha alcune definizioni di cui una clausola where, come questo:

filter a b = blahblah where 
    foo = bar 
    bar = baz 
    baz = bing 

Ma coloro tutte apparire come filter.foo, filter.bar, ecc

Ho pensato che potessero essere annidate espressioni, ma jankRoulette.select non ne ha. E ho aggiunto le direttive SCC di fronte a molti di loro senza che nessuno di quei centri di costo salisse in cima.

Poiché la maggior parte del tempo è trascorso in filter.(...), mi piacerebbe sapere di cosa si tratta. :)

+1

Come il commento di 'TODO' nel codice che le citazioni di bennofs dovrebbero suggerire, i rapporti di profiler GHC (e praticamente tutto ciò che produce il compilatore) dovrebbero sempre essere accompagnati dal risultato di' ghc --version'. – dfeuer

+0

Grazie per il promemoria! Per i posteri, ho in esecuzione The Glorious Glasgow Haskell Compilation System, versione 7.8.1. – alltom

risposta

7

TL; DR: GHC genera questo quando si esegue una corrispondenza di modello in un binding let, come let (x,y) = c. Il costo della valutazione di c è tracciato dal centro di costo ... (poiché non esiste un nome univoco) `.


Quindi, come ho trovato questo? Un grep per (...) nel codice sorgente GHC trova la seguente (dal compilatore/deSugar/Coverage.hs):

-- TODO: Revisit this 
addTickLHsBind (L pos ([email protected](PatBind { pat_lhs = lhs, pat_rhs = rhs }))) = do 
    let name = "(...)" 
    (fvs, rhs') <- getFreeVars $ addPathEntry name $ addTickGRHSs False False rhs 

    {- ... more code following, but not relevant to this purpose 
    -} 

Questo codice ci dice che ha a che fare qualcosa con le associazioni del modello. così possiamo fare un piccolo programma di test per verificare il comportamento:

x :: Int 
(x:_) = reverse [1..1000000000] 

main :: IO() 
main = print x 

Poi, siamo in grado di eseguire questo programma con profiling abilitato. Un anzi, GHC genera il seguente output:

COST CENTRE MODULE     no.  entries %time %alloc %time 

%alloc 
MAIN  MAIN      42   0 0.0 0.0 100.0 100.0 
CAF  Main      83   0 0.0 0.0 100.0 100.0 
    (...)  Main      86   1 100.0 100.0 100.0 100.0 
    x   Main      85   1 0.0 0.0  0.0 0.0 
    main  Main      84   1 0.0 0.0  0.0 0.0 

Così si scopre l'ipotesi fatta dal codice era corretta. Tutto il tempo del programma viene impiegato per valutare l'espressione reverse [1..1000000000] ed è assegnato al centro di costo (...).

+0

Amo (e totalmente simpatizzare con) il commento di 'TODO' lì: P. –

+0

Corollario: per disambiguare i centri di costo, nominare i valori prima della corrispondenza del modello, ad esempio '(x: _) = foo dove foo = reverse [1..10000000]'. Ottima risposta, bennofs, grazie mille! – alltom