我有以下内容:
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
时,a
强制b
进入弱的第一范式
对我缺少什么理解的任何指示?
答案 0 :(得分:1)
主要速度问题是将“节点”视为列表 - 您的算法通常需要在随机位置获取项目,对于链表数据结构中的每次检索都是O(n)。
将“节点”从[Node]替换为任何更适合的数据结构(Data.Map或Array)将显着提高复杂性。