根据this question,我检查了笔记本电脑的性能。
令人惊讶的是,我发现pop(0)
中的list
比popleft()
结构中的deque
快:
python -m timeit 'l = range(10000)' 'l.pop(0)'
给出:
10000次循环,最好是3次:每个循环66个usec
而:
python -m timeit 'import collections' 'l = collections.deque(range(10000))' 'l.popleft()'
给出:
10000次循环,最佳为3次:每个循环123微秒
此外,我检查了jupyter的性能,发现了相同的结果:
%timeit l = range(10000); l.pop(0)
10000个循环,每个循环最好为3:64.7 µs
from collections import deque
%timeit l = deque(range(10000)); l.popleft()
10000次循环,最好为3:每个循环122 µs
是什么原因?
最佳答案
问题在于您的timeit
调用还会对双端队列/列表的创建进行计时,并且由于链接的原因,创建deque
显然要慢得多。
在命令行中,可以使用timeit
选项将设置传递给-s
,如下所示:
python -m timeit -s"import collections, time; l = collections.deque(range(10000000))" "l.popleft()"
另外,由于安装程序仅运行一次,所以在提示之后您会收到一个弹出错误(空列表),因为我没有更改默认的迭代次数,因此我创建了一个大的双端队列来弥补它,
10000000 loops, best of 3: 0.0758 usec per loop
另一方面,使用
list
比较慢:python -m timeit -s "l = list(range(10000000))" "l.pop(0)"
100 loops, best of 3: 9.72 msec per loop
我还用一个脚本(更方便)在一个脚本中编写了基准,并进行了设置(以避免对设置进行计时),并在100000大小的列表上进行了99999次迭代:
import timeit
print(timeit.timeit(stmt='l.pop(0)',setup='l = list(range(100000))',number=99999))
print(timeit.timeit(setup='import collections; l = collections.deque(range(100000))', stmt='l.popleft()', number=99999))
毫不奇怪:
deque
获胜:2.442976927292288 for pop in list
0.007311641921253109 for pop in deque
请注意,列表的
l.pop()
在0.011536903686244897
秒内运行,按预期方式弹出最后一个元素时,这非常好。关于python - deque.popleft()vs list.pop(0),性能分析,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/44313935/