【发布时间】:2014-06-22 15:07:54
【问题描述】:
在 python 文档中,我可以看到 deque 是一个为从左侧或右侧弹出/添加项目高度优化的特殊集合。例如。文档说:
双端队列是堆栈和队列的概括(名称是 发音为“deck”,是“double-ended queue”的缩写)。双端队列 支持线程安全、内存高效的追加和弹出 在双端队列的一侧具有大致相同的 O(1) 性能 任一方向。
虽然列表对象支持类似的操作,但它们已针对 快速固定长度操作并产生 O(n) 内存移动成本 pop(0) 和 insert(0, v) 操作同时改变大小和 底层数据表示的位置。
我决定使用 ipython 进行一些比较。谁能解释我在这里做错了什么:
In [31]: %timeit range(1, 10000).pop(0)
10000 loops, best of 3: 114 us per loop
In [32]: %timeit deque(xrange(1, 10000)).pop()
10000 loops, best of 3: 181 us per loop
In [33]: %timeit deque(range(1, 10000)).pop()
1000 loops, best of 3: 243 us per loop
【问题讨论】:
-
从列表(例如
range或xrange)创建deque对象需要O(n) 时间。 -
“错误”是什么意思?你预计会发生什么?
-
同意@JayanthKoushik,在创建列表和双端队列之后时间
.pop。 -
deque 有内部锁来实现线程安全,但 list 没有。
-
@XingFei 不,collections.deque 没有内部锁。为此,您需要 Queue.Queue。但是 deque 的 append()、appendleft()、pop()、popleft() 和 len() 方法可以被认为是原子的,而不是通过契约的保证,而是通过它们在 CPython 中的实现方式。请参阅bugs.python.org/issue15329#msg199368(例如,对双端队列进行迭代不是线程安全的)。
标签: python performance data-structures benchmarking deque