2015-05-13 16 views
12

Ich suche nach Optimierungsmöglichkeiten in meinem Haskell-Programm, indem ich mit -prof kompiliere, aber ich kann die Kostenstellen, die Ellipsen enthalten, nicht interpretieren. Was sind filter.(...) und jankRoulette.select.(...)?Was bedeutet. (...) in einem .prof-Bericht bedeuten?

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 

I erzeugt, mit: $ ghc --make -rtsopts -prof -auto-all main.hs && ./main +RTS -p && cat main.prof

Die Funktion filter einige Definitionen in einer where Klausel hat, wie folgt aus:

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

Aber alle zeigen sich als filter.foo, filter.bar, etc

Ich dachte, sie könnten verschachtelt sein lassen Ausdrücke, aber jankRoulette.select hat keine. Und ich habe SCC-Richtlinien vor den meisten von ihnen hinzugefügt, ohne dass diese Kostenstellen an die Spitze gehen.

Da die meiste Zeit in filter.(...) verbracht wird, würde ich gerne wissen, was das ist. :)

+1

Da der 'TODO'-Kommentar im Code, den bennofs-Zitate vorschlagen sollten, GHC-Profiler-Berichte (und so ziemlich alles, was der Compiler ausgibt) immer mit dem Ergebnis von 'ghc --version' einhergehen sollte. – dfeuer

+0

Danke für die Erinnerung! Für die Nachwelt betreibe ich das Glorious Glasgow Haskell Compilation System, Version 7.8.1. – alltom

Antwort

7

TL; DR: GHC generiert dies, wenn Sie eine Musterübereinstimmung in einer gebundenen Bindung durchführen, z. B. let (x,y) = c. Die Kosten für die Auswertung c werden von der Kostenstelle ... verfolgt (da es keinen eindeutigen Namen dafür gibt).


Also, wie habe ich das herausgefunden? A grep für (...) im Quellcode GHC findet die folgende (von Compiler/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 
    -} 

Dieser Code sagt uns, dass es etwas mit Muster-Bindungen zu tun hat. So können wir ein kleines Testprogramm machen, das Verhalten zu überprüfen:

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

main :: IO() 
main = print x 

Dann wir dieses Programm mit Profilerstellung aktiviert laufen können. Ein in der Tat erzeugt GHC die folgende Ausgabe:

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 

So stellt sich die Annahme, aus dem Code ausgefertigt worden war korrekt. Die gesamte Zeit des Programms wird zur Auswertung des Ausdrucks reverse [1..1000000000] verwendet und der Kostenstelle (...) zugeordnet.

+0

Ich liebe (und sympathie mit) den 'TODO' Kommentar dort: P. –

+0

Korollar: Um die Kostenstellen zu disambiguieren, benennen Sie die Werte vor der Mustererkennung, wie '(x: _) = foo wobei foo = reverse [1..10000000]'. Große Antwort, Bennofs, vielen Dank! – alltom

Verwandte Themen