【发布时间】:2013-02-10 19:29:08
【问题描述】:
不幸的是,整个示例涉及大量代码。你可以看到完整的模块here(仍然不会编译),下面的伪代码函数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 = ...
对于某些参数,此代码在 ~.5 秒内运行。
我还测试了将 f 更改为 f':
f' dim ru = (g dim ru)
(我只是删除了最终的 zipWith,减少了所需的整体工作量)。
在相同的输入参数上,修改后的代码需要 4.5 秒。
在使用 optimizaiton 进行编译时会发生这种情况(使用 GHC 7.4.2、ghc -O2 以及更多优化)。快版的内核大约3000行,慢版的内核大约1900行。
这可能没什么好做的,但是什么样的 GHC 疯狂可能会导致我的程序通过减少它所做的工作而减速一个数量级? 当我最小的测试用例基本上生成超过 2000 行核心时,我怎么会发现这样的东西?
谢谢
【问题讨论】:
-
我怀疑慢版本会重新计算多态
ru,而快版本只计算一次。 -
我该如何解决这个问题,为什么会这样?
标签: performance haskell ghc