为什么将功能移到另一个模块时性能会下降?

osh*_*hko 6 performance haskell typeclass

我观察到相同的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)
Run Code Online (Sandbox Code Playgroud)

在测试通过中,我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)
Run Code Online (Sandbox Code Playgroud)
  • Main.test:这两个newArraytest两个住在Main=>没关系性能(第一2010ms运行可能是坏的,由于热身,但其余的好看)
  • SomeModule.testnewArray居住于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 readArraywriteArray在两种情况下,同一模块的输入:

import           Data.Array.MArray (MArray, readArray, writeArray)
Run Code Online (Sandbox Code Playgroud)

有什么想法会导致性能差异吗?

osh*_*hko 5

leftaroundabout评论中所建议,添加INLINE杂注即可解决此问题:

test :: MArray a t m => (t -> t) -> a Int t -> m ()
{-# INLINE test #-}
test f a =
    ...
Run Code Online (Sandbox Code Playgroud)

https://github.com/oshyshko/polymodperf/blob/master/src/SomeModule.hs#L10