GHC表现:为什么更多的工作需要更多的时间?

不幸的是,整个例子涉及很多代码。 您可以在这里看到完整的模块(仍然不能编译),下面的伪代码函数f对应于hpaste中的'FIXME'标签。

这是一个伪代码大纲:

module Test (run) where
    import Data.Vector.Unboxed as U

    run m i iters = let {get q} in do print $ testWrapper iters m q

    testWrapper :: forall i . Int -> Int -> i -> U.Vector i
    testWrapper iters m q =
        let {get test params: xs, dim, ru}
        in U.map fromIntegral (iterate (f dim ru) xs !! iters)

    {-# INLINE f #-}
    f :: (Int, Int) -> Vector r -> Vector r -> Vector r
    f dim ru = (g dim ru) . zipWith (*) ru

    {-# INLINE g #-}
    g :: (Int, Int) -> Vector r -> Vector r -> Vector r
    g dim ru = ...

对于某些参数,此代码运行时间约为0.5秒。

我也测试了将f改为f':

f' dim ru = (g dim ru)

(我简单地删除了最终的zipWith,减少了所需的整体工作)。

在相同的输入参数上,修改后的代码需要4.5秒。

这在使用优化进行编译时发生(使用GHC 7.4.2,ghc -O2以及更多优化)。 快速版本的核心是大约3000行,而慢版本的核心大约是1900行。

这可能还没有太多的继续,但是什么样的GHC疯狂可能会导致我的程序通过减少它的工作来减慢一个数量级呢? 当我最小的测试用例生成2000多行内核时,我怎么能发现这样的东西?

谢谢


查看堆配置文件。 这可能是“少工作”版本留下一些thunk未评估? 这可能导致大量内存占用,并通过垃圾回收影响速度。

链接地址: http://www.djcxy.com/p/7471.html

上一篇: GHC Performance: Why does more work take *much* less time?

下一篇: Is there a list of GHC extensions that are considered 'safe'?