用堆栈分析构建 [英] Profiling builds with stack
问题描述
如何通过 -prof
构建我的可执行文件及其所有依赖项?>
简单地将它添加到 .cabal $ c $中的
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屋!