什么。(...)在.prof报告中的含义是什么意思?

时间:2015-05-13 00:19:17

标签: haskell profiling

我正在通过使用-prof进行编译来寻找Haskell程序中的优化机会,但我不知道如何解释包含省略号的成本中心。什么是filter.(...)jankRoulette.select.(...)

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

我用$ ghc --make -rtsopts -prof -auto-all main.hs && ./main +RTS -p && cat main.prof

生成了它

函数filterwhere子句中有一些定义,如下所示:

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

但这些都显示为filter.foofilter.bar

我认为它们可能是嵌套的表达式,但jankRoulette.select没有任何表达式。而且我已经在大多数成本面前添加了SCC指令,而没有任何成本中心升至顶部。

由于大部分时间花在filter.(...)上,我想知道那是什么。 :)

1 个答案:

答案 0 :(得分:7)

TL; DR: GHC会在let绑定中执行模式匹配时生成此项,例如let (x,y) = c。评估c的费用由...费用中心跟踪(因为没有唯一的名称)`。

那我是怎么发现的呢? GHC源代码中的(...)的grep找到以下内容(来自compiler / deSugar / Coverage.hs):

-- TODO: Revisit this
addTickLHsBind (L pos (pat@(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
   -}

该代码告诉我们它必须对模式绑定做一些事情。 所以我们可以制作一个小测试程序来检查行为:

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

main :: IO ()
main = print x

然后,我们可以在启用分析的情况下运行此程序。确实,GHC产生以下输出:

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

事实证明,代码所做的假设是正确的。程序的所有时间都用于评估reverse [1..1000000000]表达式,并将其分配给(...)成本中心。