如何解决deque.popleft和list.pop0有性能差异吗?
deque.popleft()比list.pop(0)更快,这是因为deque已被优化以在O(1)中执行popleft(),而list.pop(0)需要O(n)(请参阅deque对象) 。
_collectionsmodule.c中用于deque的注释和代码以及listobject.c中用于list的注释和代码提供了实现见解,以解释性能差异。即,双端队列对象“由双向链接列表组成”,可以有效地优化两端的追加和弹出,而列表对象甚至不是单链接列表,而是C数组(指向元素的指针)(请参阅Python 2.7 listobject。 h#l22和Python 3.5 listobject.h#l23),这使其非常适合元素的快速随机访问,但在移除第一个元素之后需要O(n)时间来重新放置所有元素。
对于Python 2.7和3.5,这些源代码文件的URL为:
-
https://hg.python.org/cpython/file/2.7/Modules/_collectionsmodule.c
-
https://hg.python.org/cpython/file/3.5/Modules/_collectionsmodule.c
使用%timeit,当双端队列和列表具有相同的52个元素时,deque.popleft()和list.pop(0)之间的性能差异约为4倍,而当长度为10 ** 8。测试结果如下。
import string
from collections import deque
%timeit d = deque(string.letters); d.popleft()
1000000 loops, best of 3: 1.46 µs per loop
%timeit d = deque(string.letters)
1000000 loops, best of 3: 1.4 µs per loop
%timeit l = list(string.letters); l.pop(0)
1000000 loops, best of 3: 1.47 µs per loop
%timeit l = list(string.letters);
1000000 loops, best of 3: 1.22 µs per loop
d = deque(range(100000000))
%timeit d.popleft()
10000000 loops, best of 3: 90.5 ns per loop
l = range(100000000)
%timeit l.pop(0)
10 loops, best of 3: 93.4 ms per loop
解决方法
deque.popleft()
并且list.pop(0)
似乎返回相同的结果。它们之间有什么性能差异,为什么?
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。