使用堆栈

时间:2015-08-20 16:24:22

标签: haskell cabal haskell-stack

如何告诉stack使用-prof构建我的可执行文件及其所有依赖项?

仅仅将ghc-options文件中的.cabal添加到A B C D E 1 m 1990 1989 200 1 m 1990 1990 100 1 m 1991 1989 10 2 m 1991 1990 20 2 m 1991 1991 100 3 m 1992 1989 30 3 m 1992 1990 20 3 m 1992 1991 10 4 m 1992 1992 10 4 m 1993 1989 50 是不够的,因为它只会尝试构建启用了性能分析的可执行文件,但失败了。

4 个答案:

答案 0 :(得分:74)

使用Stack 1.0.0和更新的

进行性能分析

要在启用性能分析的情况下进行构建:

stack build --profile

您可能需要先stack clean ,但this should be fixed in Stack 1.5.0

简介:

stack exec -- <your program> +RTS <profiling options>

<profiling options>您可能需要-p进行时间分析,或-h进行内存分析。对于时间分析,配置文件显示在./<your program>.prof中,对于内存分析,配置文件显示在./<your program>.hp中。

有关更多性能分析选项,请参阅GHC profiling documentation

避免不必要的本地包重建

由于long standing Stack issue, 在分析和非分析构建之间切换可能会导致很多 不必要地重建本地包和extra-deps。上班 在此周围,您可以使用单独的构建缓存进行分析 非分析构建。例如,您使用stack <cmd>的位置 您可以使用非分析

stack --work-dir .stack-work-profile --profile <cmd>

用于<cmd>的分析版本。这使用单独的 缓存在.stack-work-profile中用于分析工件, 而非分析工件将在默认情况下保留 .stack-work缓存。

使用1.0.0之前的堆栈版本(即从2015年开始)构建分析

要在启用性能分析的情况下进行构建:

stack build --executable-profiling --library-profiling --ghc-options="-fprof-auto -rtsopts"

简介:

stack exec -- <your program> +RTS <profiling options>

Stack 1.0.0及更新版

的示例

假设您有一个名为test的程序包,其中test定义了一个可执行文件main

module Main where

main :: IO ()
main = do
  print $ foo 0

foo :: Int -> Int
foo x = fooSub (x+1)
  where
    fooSub x = bar (x+1)

bar :: Int -> Int
bar x = barSub (x+1)
  where
    barSub x = barSubSub (x+1)
      where
        barSubSub x = x+1

然后执行stack build --profile && stack exec -- test +RTS -p将生成包含

的文件./test.prof
                                                                                                individual      inherited
COST CENTRE                 MODULE                SRC                        no.     entries  %time %alloc   %time %alloc

  [... many lines omitted ...]
  main                      Main                  src/Main.hs:(4,1)-(5,15)    97          0    0.0    0.0     0.0    0.0
   foo                      Main                  src/Main.hs:(8,1)-(10,24)   98          1    0.0    0.0     0.0    0.0
    foo.fooSub              Main                  src/Main.hs:10:5-24         99          1    0.0    0.0     0.0    0.0
     bar                    Main                  src/Main.hs:(13,1)-(17,46) 100          1    0.0    0.0     0.0    0.0
      bar.barSub            Main                  src/Main.hs:(15,5)-(17,46) 101          1    0.0    0.0     0.0    0.0
       bar.barSub.barSubSub Main                  src/Main.hs:17:9-46        102          1    0.0    0.0     0.0    0.0
 main                       Main                  src/Main.hs:(4,1)-(5,15)    95          0    0.0   20.5     0.0   20.5

即,所有定义都有分析信息,包括 where子句中的本地定义。

如果您只想分析顶级定义,可以使用 改为GHC选项-fprof-auto-top:执行stack build --profile --ghc-options=-fprof-auto-top && stack exec -- test +RTS -p会产生./test.prof,其中包括

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

 [... many lines omitted ...]
  main      Main                  src/Main.hs:(4,1)-(5,15)    97          0    0.0    0.0     0.0    0.0
   foo      Main                  src/Main.hs:(8,1)-(10,24)   98          1    0.0    0.0     0.0    0.0
    bar     Main                  src/Main.hs:(13,1)-(17,46)  99          1    0.0    0.0     0.0    0.0
 main       Main                  src/Main.hs:(4,1)-(5,15)    95          0    0.0   20.5     0.0   20.5

代替。

最后,请注意stack build --profile也会打开堆栈 痕迹。如果您更改程序以便barSubSub x = error $ show x,则运行stack build --profile && stack exec test会生成

test: 4
CallStack (from HasCallStack):
  error, called at src/Main.hs:17:23 in main:Main
CallStack (from -prof):
  Main.bar.barSub.barSubSub (src/Main.hs:17:9-36)
  Main.bar.barSub (src/Main.hs:(15,5)-(17,36))
  Main.bar (src/Main.hs:(13,1)-(17,36))
  Main.foo.fooSub (src/Main.hs:10:5-24)
  Main.foo (src/Main.hs:(8,1)-(10,24))
  Main.main (src/Main.hs:(4,1)-(5,15))
  Main.CAF:lvl8_r4Fc (<no location info>)

非常酷!

答案 1 :(得分:14)

我也有这个问题,发现问题出在调用中:

stack exec my-exe +RTS -p将-p传递给堆栈而不是my-exe。这有效:

stack exec -- my-exe +RTS -p

答案 2 :(得分:4)

对于stack buildstack benchstack test,您只需使用stack build/bench/test --profile。您可能必须先stack clean才能通过分析重新编译它。

对于stack build,在GHC User Guide中运行可执行文件时,您仍需要传递+RTS -p或任何您需要的选项(请参阅@Tomáš Janoušek answer)。

您还可以在debugging section of the stack user guide

中找到更多信息

答案 3 :(得分:0)

假设一个名为project-name的项目,这就是我获得时间和堆配置文件(带有颜色)的方法:

  1. 将依存关系添加到build-depends的{​​{1}}部分
  2. 获取相关软件包:project-name.cabal
  3. stack build内部使用profiling enabled编译程序:project-name/app
  4. 然后创建heaptime个人资料stack ghc -- -prof -fprof-auto -rtsopts -O2 Main.hs。这将产生./Main +RTS -hc -pMain.hp
  5. 将堆配置文件转换为PostScript file,然后转换为颜色为Main.prof的PDF图表

这是PDF中的堆配置文件:

heap_profile_with_colors