Распределение функций классов типов в выходных данных профилировщика GHC - PullRequest
8 голосов
/ 11 мая 2010

При профилировании программы на Haskell, написанной на GHC, имена функций классов типов вносятся в файл .prof, чтобы отличать их реализации одного экземпляра от другого. Как я могу разобрать эти имена, чтобы выяснить, к какому экземпляру относится этот тип?

Например, предположим, у меня есть следующая программа, где типы Fast и Slow оба реализуют Show:

import Data.List (foldl')

sum' = foldl' (+) 0

data Fast = Fast
instance Show Fast where
    show _ = show $ sum' [1 .. 10]

data Slow = Slow
instance Show Slow where
    show _ = show $ sum' [1 .. 100000000]

main = putStrLn (show Fast ++ show Slow)

Я компилирую с -prof -auto-all -caf-all и запускаю с +RTS -p. В сгенерированном файле .prof я вижу, что главные центры затрат:

COST CENTRE                    MODULE               %time %alloc

show_an9                       Main                  71.0   83.3
sum'                           Main                  29.0   16.7

И в дереве я также вижу (опуская нерелевантные строки):

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

  main            Main         232           1   0.0    0.0   100.0  100.0
   show_an9       Main         235           1  71.0   83.3   100.0  100.0
    sum'          Main         236           0  29.0   16.7    29.0   16.7
   show_anx       Main         233           1   0.0    0.0     0.0    0.0

Как мне выяснить, что show_an9 является реализацией Slow show, а не Fast?

1 Ответ

8 голосов
/ 11 мая 2010

Нет, ты не можешь. Части _an9 и _anx генерируются случайным образом. (Когда я снова компилирую, я получаю _ane и _anC.)

Вы можете использовать прагму SCC (set-cost-center) для ручной вставки МВЗ:

data Fast = Fast
instance Show Fast where
    show _ = {-# SCC "show(Fast)" #-} show $ sum' [1 .. 10]

data Slow = Slow
instance Show Slow where
    show _ = {-# SCC "show(Slow)" #-} show $ sum' [1 .. 100000000]

Профиль должен показывать:

  main
   show_an9
    show(Slow)
     sum'
   show_anx
    show(Fast)
...