用堆栈分析构建 [英] Profiling builds with stack

查看:97
本文介绍了用堆栈分析构建的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何通过 -prof 构建我的可执行文件及其所有依赖项?>

简单地将它添加到 .cabal ghc-options c>文件是不够的,因为它只会尝试构建启用了配置文件的可执行文件,从而失败。 解析方案

Stack 1.0.0和更新版本



在启用分析功能的情况下构建:

  stack build --profile 

您可能需要运行堆栈干净第一,但这应该在Stack 1.5中解决。 0



简介:

  stack exec - <你的程序> + RTS<分析选项> 

其中<分析选项> 您可能需要用于时间分析的 -p 或用于内存分析的 -h 。对于时间分析,配置文件显示在 ./& lt;程序> .prof 中,而对于内存分析,配置文件显示在 ./<您的程序> .hp



请参阅 GHC分析文档以获取更多分析选项。



避免不必要的重建本地软件包

h1>

由于长期堆叠
问题

在概要分析和非概要分析构建之间切换会导致大量
的本地程序包不必要的重建,并且 extra-deps 。为了在此工作
,可以使用单独的构建缓存来进行性能分析和
的非性能分析构建。例如,对于
非概要分析,您可以使用 stack< cmd> ,您可以使用

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

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



在1.0.0之前使用Stack版本进行性能分析(即从2015年开始)



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

  stack build --executable-分析 - 库分析--ghc-options = -  fprof-auto -rtsopts

profile:

  stack exec  - < your program> + RTS<分析选项> 



Stack 1.0.0及更新版本的示例



<假设你有一个名为 test 的包,其中包含一个由 main定义的可执行文件 test / code> here:


 模块Main其中

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

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

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

然后执行 stack build --profile&& stack exec - test + RTS -p 会生成一个 ./ test.prof 文件,其中包括

 个人继承
成本中心模块SRC no。项目%时间%分配%时间%分配

[...多行忽略...]
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主src / Main.hs: 10:5-24 99 1 0.0 0.0 0.0 0.0
bar主src / Main.hs:(13,1) - (17,46)100 1 0.0 0.0 0.0 0.0
bar.barSub主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



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

想要描述顶级定义,您可以使用
构建GHC选项 -fprof-auto-top ,而不是:执行堆栈构建 - -profile --ghc-options = -fprof-auto-top&& stack exec - test + RTS -p 产生一个 ./ test.prof ,其中包括

 个人继承
成本中心模块SRC no。项目%时间%分配%时间%分配

[...多行忽略...]
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主要src / Main.hs:(4,1) - (5,15)95 0 0.0 20.5 0.0 20.5

改为。



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

  test:4 
CallStack(来自HasCallStack):
错误,在src / Main.hs:17:23中调用main:Main
CallStack(来自-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>)

很酷!


How do I tell stack to build my executable and all its dependencies with -prof?

Simply adding it to ghc-options in the .cabal file is not enough, because it only tries to build the executable with profiling enabled, which fails.

解决方案

Profiling builds with Stack 1.0.0 and newer

To build with profiling enabled:

stack build --profile

You may need to run stack clean first, but this should be fixed in Stack 1.5.0.

To profile:

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

where for <profiling options> you might want -p for time profiling or -h for memory profiling. For time profiling, the profile appears in ./<your program>.prof, and for memory profiling, the profile appears in ./<your program>.hp.

See GHC profiling documentation for more profiling options.

Avoiding unnecessary rebuilding of local packages

Due to a long standing Stack issue, switching between profiling and non-profiling builds can cause a lot of unnecessary rebuilding of local packages and extra-deps. To work around this, you can use separate build caches for your profiling and non-profiling builds. For example, where you use stack <cmd> for non profiling you can use

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

for a profiling version of <cmd>. This uses a separate cache in .stack-work-profile for profiling artifacts, whereas non profiling artifacts will be preserved in the default .stack-work cache.

Profiling builds with Stack versions before 1.0.0 (i.e. from 2015)

To build with profiling enabled:

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

To profile:

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

Example for Stack 1.0.0 and newer

Suppose you have a package called test with a single executable test defined by main here:

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

then doing stack build --profile && stack exec -- test +RTS -p will produce a file ./test.prof which includes

                                                                                                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

I.e., there is profiling information for all definitions, including local definitions in where clauses.

If you only want to profile top-level definitions, you can build with the GHC option -fprof-auto-top instead: doing stack build --profile --ghc-options=-fprof-auto-top && stack exec -- test +RTS -p produces a ./test.prof which includes

                                                                                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

instead.

Finally, note that stack build --profile also turns on stack traces. If you change the program so that barSubSub x = error $ show x, then running stack build --profile && stack exec test produces

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

Pretty cool!

这篇关于用堆栈分析构建的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆