GHCのプロファイル機能がCabalのエラーで動かなかったことを解決しました
問題
stack bench --profile
が失敗します。
動機
パフォーマンスチューニングを行いたい場合、当然まずは計測をすることになります。
Haskell(GHC)にはそれなりに良いプロファイラが付属しているため、まずはこれを使って計測をするのが早道だと思います。
既に他のメンバーによって最適化の数値を計測しやすくするため、
benchmarks
がtasty-bench
によって実装されているため、このベンチマークで動く処理のプロファイルを取るのが早道でしょう。
期待される動作
stack bench --profile
でプロファイル有効でベンチマークが動く。
実際の動作
-- While building package foo-0.1.0 (scroll up to its section to see the error) using:
/home/ncaq/Desktop/foo/.stack-work/dist/x86_64-linux-tinfo6/Cabal-3.2.1.0/setup/setup --builddir=.stack-work/dist/x86_64-linux-tinfo6/Cabal-3.2.1.0 bench bar-bench "--benchmark-options=+RTS -p -RTS +RTS -T --nonmoving-gc"
Process exited with code: ExitFailure 1
のように失敗する。
バージョン読み込み失敗問題はstack clean --full
で解決します
RIOを使っていて、 gitのHEADを見るからか、
/home/ncaq/Desktop/foo/app/Main.hs:28:5: fatal:
cannot find object file ‘.stack-work/dist/x86_64-linux-tinfo6/Cabal-3.2.1.0/build/foo/foo-tmp/Paths_foo.dyn_o’
while linking an interpreted expression
のようにバージョン読み込みに失敗することがありますが、これはstack clean --full
で解決します。
問題の本質
この問題はStackではなくCabalの問題で、 Profiling executables which use Template Haskell fails · Issue #5961 · haskell/cabal にissueが開かれています。
TemplateHaskell
が絡むと問題が発生するようですね。
解決探索
issueに従って、
other-extensions: TemplateHaskell
を書いていきましょう。
other-extensions
ってなんだ…?
Document other-extensions
in user guide · Issue #1517 · haskell/cabal
によると使われる可能性のある拡張を指定できるらしい。いや書かなくても使えるのだがどういうことだろう。
まあ何にせよTemplateHaskell
は実際に使っているのでトップレベルのother-extensions
に指定しましょう。同じくエラーになりますね…
本当はしたくないですがdefault-extensions
に指定してみますか。これで動くか確かめます。動かないですね…
おかしいなあ、他のプロジェクトではこれで回避してるのですが…
stack.yaml
に書いてた記述が問題っぽかったです。
tasty-bench がメモリ使用量を測るためのオプションとして推奨していたので以下のように書いていたのですが、これが引っかかったようですね。
build:
bench: false
benchmark-opts:
benchmark-arguments: "+RTS -T --nonmoving-gc"
Note that --nonmoving-gc cannot be used with -G1, profiling nor -c.
5.7. Running a compiled program — Glasgow Haskell Compiler 9.0.1 User's Guide
グエーちゃんとプロファイルとは併用できないとGHCの公式ガイドに書かれている。
よってこれも削除することでプロファイルが動くようになりました。
解決方法まとめ
other-extensions: TemplateHaskell
を書く--nonmoving-gc
を消去する
の2つで今回は動かせるようになりました。
CabalとStackのレイヤーに阻まれたのか、 GHCのエラーメッセージがマトモに出なくて、色々探す苦労をすることになりました。