haskell - 使用 Stack 分析构建

标签 haskell cabal haskell-stack

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

仅将其添加到 .cabal 文件中的 ghc-options 是不够的,因为它仅尝试构建启用分析的可执行文件,但会失败。

最佳答案

使用 Stack 1.0.0 及更高版本分析构建

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

stack build --profile

您可能需要运行 stack clean首先,但是this should be fixed in Stack 1.5.0 .

查看个人资料:

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

<profiling options>在哪里你可能想要-p用于时间分析或 -h用于内存分析。对于时间分析,配置文件显示在./<your program>.prof中。 ,对于内存分析,该分析显示在 ./<your program>.hp 中。 .

参见GHC profiling documentation了解更多分析选项。

避免不必要地重建本地包(在 Stack 2.X 中修复了吗?)

由于 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 之前的 Stack 版本(即从 2015 年开始)分析构建

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

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

查看个人资料:

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

堆栈 1.0.0 及更高版本的示例

假设您有一个名为 test 的包具有单个可执行文件 testmain 定义这里:

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>)

非常酷!

关于haskell - 使用 Stack 分析构建,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32123475/

相关文章:

haskell - haskell 堆栈的基本用法失败

haskell - OSX 10.13.4 上堆栈安装 ghc-mod 因依赖项冲突而失败

haskell-stack - 堆栈构建错误 : attribute ‘ghc822’ missing,(字符串):1:53

multithreading - 如何从 fork 线程安全地使用 WebKitGTK?

haskell - 简化嵌套的 Maybe 模式匹配

haskell - 强制使用本地文件的 GHC

haskell - 如何使用比 Stackage Resolver 可用的更新版本的库

haskell - 在 Haskell 中解析大型日志文件

haskell - 如何从有向无环图导出 FRP?

haskell - cabal (依赖) hell 背后的原因是什么?