如果我在同一个模块中测量它,我有一个非递归函数来计算似乎表现良好的最长公共子序列(用标志ghc 7.6.1
编译)。另一方面,如果我将函数转换为模块,仅导出该函数(如此处推荐的),然后使用 Criterion 再次测量,我会得到约 2 倍的减速(如果我将标准测试移回模块,它就会消失其中定义了函数)。我尝试用pragma 标记函数,这对跨模块性能测量没有任何影响。-O2 -fllvm
Criterion
INLINE
在我看来,GHC 可能会进行严格性分析,当函数和主函数(从该函数可以访问)在同一个模块中时效果很好,但当它们被拆分时则不行。我会很感激有关如何模块化函数的指针,以便在从其他模块调用时它可以很好地执行。有问题的代码太大,无法粘贴到此处 -如果您想尝试一下,可以在此处查看。下面是我正在尝试做的一个小例子(带有代码片段):
-- 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
--}