应用seq来改善Haskell中的执行时间

时间:2012-11-03 05:12:38

标签: haskell ghc lazy-evaluation execution-time seq

我有以下内容:

data Node = Node { position::Int
                 , zombies::Float
                 , connections::[Int]
                 }

moveZombie :: [Node] -> Node -> Node
moveZombie nodes (Node i _ cx) = zc `seq` Node i zc cx
  where zc = sum [zombies n / (fromIntegral $ length $ connections n) | i <- cx, let n = nodes !! i]

step :: Int -> [Node] -> [Node]
step 0 nodes = nodes
step k nodes = step (k-1) $ map (moveZombie nodes) nodes

在GHC中启用性能分析编译告诉我成本中心是:

                               Individual
COST CENTRE            MODULE %time %alloc
moveZombie.zc          Main   60.3   90.4
moveZombie.zc.n        Main   37.6    0.0

我尝试了以下方法:moveZombie nodes (Node i _ cx) = zc `seq` Node i zc cx强制进行严格评估,让程序运行得更快,但完全不成功。我知道我对seq的工作方式的理解有问题,但我似乎无法弄清楚是什么。

我认为,我需要强制对step k nodes = step (k-1) $ map (moveZombie nodes) nodes进行严格评估,但我很困惑。

我知道:

    在评估seq a b 时,
  1. a强制b进入弱的第一范式
  2. 如果最外层表达式是lambda或Data构造函数
  3. ,则表达式为弱正规形式

    对我缺少什么理解的任何指示?

1 个答案:

答案 0 :(得分:1)

主要速度问题是将“节点”视为列表 - 您的算法通常需要在随机位置获取项目,对于链表数据结构中的每次检索都是O(n)。

将“节点”从[Node]替换为任何更适合的数据结构(Data.Map或Array)将显着提高复杂性。