我观察到相同的 fn 提供不同的性能,这取决于它是放置在使用它的同一模块中还是放置在它旁边的模块中。有什么想法可能导致它吗?
这是功能:
https://github.com/oshyshko/polymodperf/blob/master/src/Main.hs#L41-L55
test :: MArray a t m => (t -> t) -> a Int t -> m ()
test f a =
mapM_ (\ xy -> do
v <- get a xy
set a xy (f v))
[ (x,y) | y <- [0..1000 - 1],
x <- [0..1000 - 1],
n <- [0..10]]
where
get :: MArray a e m => a Int e -> (Int, Int) -> m e
get a (x,y) = readArray a (x + y * 1000)
set :: MArray a e m => a Int e -> (Int, Int) -> e -> m ()
set a (x,y) = writeArray a (x + y * 1000)
在我的测试通过中,我使用
Data.Array.IO.newArray
创建一个数组,然后将其传递给 test
.以下是观察性能差异的方法(第二个值,ms):
$ ./scripts/build-exec.sh
...
Main.test
(11000000,2010)
(11000000,239)
(11000000,240)
(11000000,242)
(11000000,237)
SomeModule.test
(11000000,6376)
(11000000,4851)
(11000000,5455)
(11000000,5096)
(11000000,5206)
Main.test
: 两个newArray
和 test
都住在Main
=> 好的性能(前 2010 毫秒的运行可能由于预热而很糟糕,但其余看起来不错)SomeModule.test
: newArray
住在Main
, 但是 test
从 SomeModule.test
导入=> 性能更差test
的代码在两个模块中是相同的:https://github.com/oshyshko/polymodperf/blob/master/src/Main.hs#L41-L55
https://github.com/oshyshko/polymodperf/blob/master/src/SomeModule.hs#L9-L17
使用过的
MArray
类型和 fns readArray
, writeArray
在这两种情况下从同一个模块导入:import Data.Array.MArray (MArray, readArray, writeArray)
任何想法可能导致性能差异?
最佳答案
如leftaroundabout
在评论中建议,添加 INLINE
pragma 解决了这个问题:
test :: MArray a t m => (t -> t) -> a Int t -> m ()
{-# INLINE test #-}
test f a =
...
https://github.com/oshyshko/polymodperf/blob/master/src/SomeModule.hs#L10
关于performance - 为什么将函数移到另一个模块时性能会下降?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56322038/