如何告诉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
是不够的,因为它只会尝试构建启用了性能分析的可执行文件,但失败了。
答案 0 :(得分:74)
要在启用性能分析的情况下进行构建:
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
缓存。
要在启用性能分析的情况下进行构建:
stack build --executable-profiling --library-profiling --ghc-options="-fprof-auto -rtsopts"
简介:
stack exec -- <your program> +RTS <profiling options>
假设您有一个名为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 build
,stack bench
和stack test
,您只需使用stack build/bench/test --profile
。您可能必须先stack clean
才能通过分析重新编译它。
对于stack build
,在GHC User Guide中运行可执行文件时,您仍需要传递+RTS -p
或任何您需要的选项(请参阅@Tomáš Janoušek answer)。
答案 3 :(得分:0)
假设一个名为project-name
的项目,这就是我获得时间和堆配置文件(带有颜色)的方法:
build-depends
的{{1}}部分project-name.cabal
stack build
内部使用profiling enabled编译程序:project-name/app
stack ghc -- -prof -fprof-auto -rtsopts -O2 Main.hs
。这将产生./Main +RTS -hc -p
和Main.hp
Main.prof
的PDF图表这是PDF中的堆配置文件: