【发布时间】:2011-11-18 00:55:52
【问题描述】:
我一直在尝试在 Python 中优化 BFS 实现的性能,我最初的实现是使用 deque 来存储要扩展的节点队列和 dict 来存储相同的节点,这样我就可以有效地查找它是否已经打开了。
我尝试通过迁移到 OrderedDict 来优化(简单性和效率)。然而,这需要更多的时间。使用 deque/dict 完成 400 个样本搜索需要 2 秒,而仅使用 OrderedDict 则需要 3.5 秒。
我的问题是,如果 OrderedDict 的功能与两个原始数据结构相同,那么它至少在性能上不应该相似吗?或者我在这里错过了什么?下面的代码示例。
仅使用 OrderedDict:
open_nodes = OrderedDict()
closed_nodes = {}
current = Node(start_position, None, 0)
open_nodes[current.position] = current
while open_nodes:
current = open_nodes.popitem(False)[1]
closed_nodes[current.position] = (current)
if goal(current.position):
return trace_path(current, open_nodes, closed_nodes)
# Nodes bordering current
for neighbor in self.environment.neighbors[current.position]:
new_node = Node(neighbor, current, current.depth + 1)
open_nodes[new_node.position] = new_node
同时使用双端队列和字典:
open_queue = deque()
open_nodes = {}
closed_nodes = {}
current = Node(start_position, None, 0)
open_queue.append(current)
open_nodes[current.position] = current
while open_queue:
current = open_queue.popleft()
del open_nodes[current.position]
closed_nodes[current.position] = (current)
if goal_function(current.position):
return trace_path(current, open_nodes, closed_nodes)
# Nodes bordering current
for neighbor in self.environment.neighbors[current.position]:
new_node = Node(neighbor, current, current.depth + 1)
open_queue.append(new_node)
open_nodes[new_node.position] = new_node
【问题讨论】:
-
OrderedDict是用 Python 实现的,而dict和deque都是用 C 实现的。deque和dict的组合不允许实现OrderedDict具有与当前实现相同的运行时保证。例如,从OrderedDict中删除一个项目是摊销 O(1),这对于基于dict和deque的实现是不可能的。好吧,如果你幸运的话,雷蒙德会加入并给你一个权威的答案。 :) -
如果你使用 python 2.7 并且想要克服 OrderedDict 的性能问题,你可以看看这个项目 - github.com/shoyer/cyordereddict,OrderedDict 的 Cython 实现。
标签: python performance algorithm optimization