同じモジュール内でCriterion
と測定すると、よく実行されると思われる最長共通部分シーケンスを計算する非再帰関数があります(ghc 7.6.1
、-O2 -fllvm
フラグでコンパイルされます)。私は(推奨hereなど)モジュール、輸出がちょうどその関数に関数を変換し、基準を再び測定した場合、私は戻ってモジュールに基準テストを移動した場合一方、私が消える〜2倍の減速を(取得します関数が定義されている場所)。私はINLINE
プラグマで関数をマークしてみましたが、これはモジュール間の性能測定に何の違いもありませんでした。GHCのモジュール間最適化
GHCは、関数とメイン(関数が到達可能)が同じモジュール内にあるときにうまく機能する厳密性分析を行っている可能性があります。関数をモジュール化して、他のモジュールから呼び出されたときにうまく機能するようにする方法についての指摘を感謝します。問題のコードは大きすぎてここに貼り付けることはできません。試してみたい場合はhereをご覧ください。私がやろうとしています何の小さな例は、以下の(コードのスニペットを持つ)である:
-- Function to find longest common subsequence given unboxed vectors a and b
-- It returns indices of LCS in a and b
lcs :: (U.Unbox a, Eq a) => Vector a -> Vector a -> (Vector Int,Vector Int)
lcs a b | (U.length a > U.length b) = lcsh b a True
| otherwise = lcsh a b False
-- This section below measures performance of lcs function - if I move it to
-- a different module, performance degrades ~2x - mean goes from ~1.25us to ~2.4us
-- on my test machine
{--
config :: Config
config = defaultConfig { cfgSamples = ljust 100 }
a = U.fromList ['a'..'j'] :: Vector Char
b = U.fromList ['a'..'k'] :: Vector Char
suite :: [Benchmark]
suite = [
bench "lcs 10" $ whnf (lcs a) b
]
main :: IO()
main = defaultMainWith config (return()) suite
--}
代わりにINLINEABLEを試してみてください。それはうまくいくかもしれません。 – Carl
@Carlは、lcs機能を試しました。まだ同じ。 – Sal
GHCはすべてが1つのモジュールに入っているときに、型変数 'a'を' Char'に特化することができるという問題があると考えています。あなたは 'SPECIALIZE'プラグマを使って遊んでみることができます(または単に' Char'に手動で変更してください)。 – hammar