【问题标题】:What does .(...) mean in a .prof report mean?.(...) 在 .prof 报告中是什么意思?
【发布时间】:2015-07-24 01:49:54
【问题描述】:

我正在通过使用-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 等。

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

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

【问题讨论】:

  • 正如代码 bennofs 引号中的 TODO 注释所暗示的那样,GHC 分析器报告(以及编译器输出的几乎所有内容)应始终伴随着 ghc --version 的结果。
  • 感谢提醒!为了后代,我碰巧正在运行 Glorious Glasgow Haskell 编译系统,版本 7.8.1。

标签: haskell profiling


【解决方案1】:

TL; DR: 当你在 let 绑定中进行模式匹配时,GHC 会生成这个,比如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] 表达式,并将其分配给(...) 成本中心。

【讨论】:

  • 我喜欢(并且完全同情)TODO 那里的评论:P。
  • 推论:为了消除成本中心的歧义,在模式匹配之前命名值,例如(x:_) = foo where foo = reverse [1..10000000]。很好的答案,本诺夫,非常感谢!
猜你喜欢
  • 1970-01-01
  • 2019-09-17
  • 2014-09-10
  • 1970-01-01
  • 2013-08-24
  • 2010-10-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多