チェックアウトcollections.deque
。ドキュメントから:
Dequeは、スレッドセーフでメモリ効率の高い追加と、Dequeの両側からのポップをサポートし、どちらの方向でもほぼ同じO(1)パフォーマンスを実現します。
リストオブジェクトは同様の操作をサポートしますが、高速の固定長操作用に最適化されており、基になるデータ表現のサイズと位置の両方を変更するpop(0)およびinsert(0、v)操作のO(n)メモリ移動コストが発生します。
それが言うように、pop(0)またはinsert(0、v)を使用すると、リストオブジェクトに大きなペナルティが発生します。でスライス/インデックス操作を使用することはできませんが、操作が最適化されている/deque
を使用することはできます。これを実証するための簡単なベンチマークは次のとおりです。popleft
appendleft
deque
import time
from collections import deque
num = 100000
def append(c):
for i in range(num):
c.append(i)
def appendleft(c):
if isinstance(c, deque):
for i in range(num):
c.appendleft(i)
else:
for i in range(num):
c.insert(0, i)
def pop(c):
for i in range(num):
c.pop()
def popleft(c):
if isinstance(c, deque):
for i in range(num):
c.popleft()
else:
for i in range(num):
c.pop(0)
for container in [deque, list]:
for operation in [append, appendleft, pop, popleft]:
c = container(range(num))
start = time.time()
operation(c)
elapsed = time.time() - start
print "Completed %s/%s in %.2f seconds: %.1f ops/sec" % (container.__name__, operation.__name__, elapsed, num / elapsed)
私のマシンでの結果:
Completed deque/append in 0.02 seconds: 5582877.2 ops/sec
Completed deque/appendleft in 0.02 seconds: 6406549.7 ops/sec
Completed deque/pop in 0.01 seconds: 7146417.7 ops/sec
Completed deque/popleft in 0.01 seconds: 7271174.0 ops/sec
Completed list/append in 0.01 seconds: 6761407.6 ops/sec
Completed list/appendleft in 16.55 seconds: 6042.7 ops/sec
Completed list/pop in 0.02 seconds: 4394057.9 ops/sec
Completed list/popleft in 3.23 seconds: 30983.3 ops/sec
.append()
、.pop()
O(1)で償却されることに注意してください(再割り当てとコピーは発生しますが、スタックが最大サイズに達するまでは非常にまれです。これまでに持っている)。