haskell-jp / questions #102 at 2022-10-28 09:39:11 +0900

ForeignPtrにcの関数をセットするaddCFinalizerToWeak#があるのですが、
呼び出しに200nsほどかかります。(条件によって変わってきますが。)
https://hackage.haskell.org/package/ghc-prim-0.5.2.0/docs/GHC-Prim.html#v:addCFinalizerToWeak-35-
https://gitlab.haskell.org/ghc/ghc/-/blob/master/rts/PrimOps.cmm#L832-871
どこにそんなに時間がかかっていると思いますか?
( LOCK_CLOSURE、updateRemembSetPushPtr、 recordMutableのどれかがほとんどの時間が使っていると思いますが。)
どうしたら内部の関数のマイクロベンチマークがとれますか?
updateRemembSetPushPtrとrecordMutableを抜いたaddCFinalizerToWeak#を作ってみましたが、
ほとんど変わらなかったです。(10ns以下の変化)
LOCK_CLOSUREが問題だとすると
weak pointerをつくってからcのfinallizerをセットするのではなくて、
weak pointerつくるときに直接cのfinalizerをセットすれば速くなりそうですね。
https://github.com/junjihashimoto/ffi-benchmark/
LOCKなしのものを作ってみましたが、まったく変わらなかったです。
結果は上記gitのbenchmark.htmlにあります。
なぜ遅いのか原因がわかりません。
weak pointerのリストのつくったあとに、cのfinalizerのリストをつくっていますが、そもそもcのfinalizerを複数登録する必要はあまりなさそうな気がしますね。