根据this question,我检查了笔记本电脑的性能。

令人惊讶的是,我发现pop(0)中的listpopleft()结构中的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/

10-12 03:26