Python 为什么Pypy';deque这么慢?
这里有一个(稍微混乱的)尝试 我应该直截了当地说,Python 为什么Pypy';deque这么慢?,python,deque,pypy,Python,Deque,Pypy,这里有一个(稍微混乱的)尝试 我应该直截了当地说,deque不是一个好选择!我的想法是,缩小用于测试成员资格的素数集将导致循环加速。然而,当我意识到我应该使用集合(不用担心删除元素)时,我的速度提高了60倍 from collections import deque from itertools import permutations from .sieve import sieve_of_erastothenes # my own implementation of the Sieve of
deque
不是一个好选择!我的想法是,缩小用于测试成员资格的素数集将导致循环加速。然而,当我意识到我应该使用集合
(不用担心删除元素)时,我的速度提高了60倍
from collections import deque
from itertools import permutations
from .sieve import sieve_of_erastothenes # my own implementation of the Sieve of Erastothenes
primes = deque(prime for prime in sieve_of_erastothenes(10000) if prime > 1000 and prime != 1487) # all four-digit primes except 1487
try:
while True:
prime = primes.popleft() # decrease the length of primes each time to speed up membership test
for inc in xrange(1,10000 + 1 - (2 * prime)): # this limit ensures we don't end up with results > 10000
inc1 = prime + inc
inc2 = prime + 2*inc
if inc1 in primes and inc2 in primes:
primestr = str(prime)
perms = set(''.join(tup) for tup in permutations(primestr)) # because permutations() returns tuples
inc1str = str(inc1)
inc2str = str(inc2)
if inc1str in perms and inc2str in perms:
print primestr + inc1str + inc2str
raise IOError # I chose IOError because it's unlikely to be raised
# by anything else in the block. Exceptions are an easy
# way to break out of nested loops.
except IOError:
pass
无论如何,在我想使用集合之前,我在Pypy中试用了它。我发现结果相当令人惊讶:
$ time python "problem49-deque.py"
296962999629
real 1m3.429s
user 0m49.779s
sys 0m0.335s
$ time pypy-c "problem49-deque.py"
296962999629
real 5m52.736s
user 5m15.608s
sys 0m1.509s
为什么Pypy在这段代码上的速度要慢五倍以上?我猜Pypy版本的deque
是罪魁祸首(因为它在集合版本上运行得更快),但我不知道为什么会这样。缓慢的部分是素数中的inc1和素数中的inc2
。我来看看为什么PyPy这么慢(基本上感谢性能缺陷报告)。请注意,正如您所提到的,代码可以变得非常快(在PyPy和CPython上)——在这种情况下,只需将素数
deque复制到for
循环之前的一个集合中即可。您应该期望deque中的成员资格测试(具有python性能特征)会很慢,因为列表中的任何成员测试都涉及线性扫描。相比之下,set是一种为成员资格测试而优化的数据结构。从这个意义上说,这里没有bug。+1,但我还没有接受答案,因为它还没有回答问题。如果你发现了问题所在,请你向我汇报好吗?我很想知道是什么原因造成的。官方的bug追踪器移动了:(当然,它从现在起就被修复了。)我的问题是关于CPython的deque
和Pypy的deque
在速度上的差异。我同意(见问题)在这种特殊情况下,set
是数据结构的正确选择,而deque
则不是。@poorsod-right,但您的问题是“为什么不适当的数据结构表现不佳”。答案是这是不合适的,而且这是事先知道的。CPython成员资格测试代码得到高度优化是好的,但CPython代码没有得到高度优化也不是坏的,因为这不是一种适用于许多此类测试的数据结构。我很好奇Pypy的成员资格测试比CPython的慢这么多的确切原因。如果你觉得这个问题在那一点上不清楚,我会编辑它。@poorsod并不是说它不清楚。这是因为你不能简单地坚持人们只对你的问题中你想限制的部分发表评论,不管出于什么原因。我认为@poorsod的问题是合法的,这也是我关注这条线索的唯一原因。我明白了,我想他也明白了,那一套才是最好的选择。但是,作为一个对PyPy和动态JIT实现的发展感兴趣的人,诊断给定行为为什么会表现出自身,这通常会揭示引擎本身。这才是真正令人感兴趣的地方。我想,他是否应该用这种欲望敲诈一个答案是另一个问题。也许这就是你想开车回家的原因谢谢你问这个问题!我正要发帖问为什么我的代码的deque版本比list版本慢28%。