performance - 为什么将函数移到另一个模块时性能会下降?

标签 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)

在我的测试通过中,我使用 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 : 两个newArraytest都住在Main => 好的性能(前 2010 毫秒的运行可能由于预热而很糟糕,但其余看起来不错)
  • SomeModule.test : newArray住在Main , 但是 testSomeModule.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/

    相关文章:

    mysql - 磁盘 IO 与 PHP 中的 MySQL 查询

    sql - 如何根据行类型获取每种类型的最新行并执行计算?

    haskell - 将 C++ 库与 Haskell 库静态链接

    haskell - 如何调用 “--enable-stdcall-fixup” 选项?

    haskell - 类型类及其实例之间的 ScopedTypeVariables

    Ruby:避免多个 "or"语句?

    php - 性能:在单个查询而不是多个查询中从 5 个表获取并分组产品详细信息?

    haskell - 标准 Haskell 函数::(a -> Maybe b) -> [a] -> Maybe b

    haskell - 如何(或为什么) `Data.Set String` 不是单一类型?

    haskell - 重载函数名称的更简单语法