我有这个简单的代码帮助我衡量__slots__
的课程表现如何(取自here):
import timeit
def test_slots():
class Obj(object):
__slots__ = ('i', 'l')
def __init__(self, i):
self.i = i
self.l = []
for i in xrange(1000):
Obj(i)
print timeit.Timer('test_slots()', 'from __main__ import test_slots').timeit(10000)
如果我通过python2.7运行它 - 我会在6秒左右得到一些东西 - 好吧,它比没有插槽时更快(并且内存效率更高)。
但是,如果我在PyPy下运行代码(使用2.2.1 - 64位用于Mac OS / X),它开始使用100%CPU和#34;从不"返回(等待几分钟 - 没有结果)。
发生了什么事?我应该在PyPy下使用__slots__
吗?
如果我将不同的号码传递给timeit()
timeit(10) - 0.067s
timeit(100) - 0.5s
timeit(1000) - 19.5s
timeit(10000) - ? (probably more than a Game of Thrones episode)
提前致谢。
请注意,如果我使用namedtuple
s:
import collections
import timeit
def test_namedtuples():
Obj = collections.namedtuple('Obj', 'i l')
for i in xrange(1000):
Obj(i, [])
print timeit.Timer('test_namedtuples()', 'from __main__ import test_namedtuples').timeit(10000)
答案 0 :(得分:11)
在timeit
代码的10,000次左右迭代中,每次从头开始重新创建该类。在PyPy中创建类可能不是一个优化良好的操作;更糟糕的是,这样做可能会放弃JIT所学到的关于该类之前版本的所有优化。在JIT预热之前,PyPy往往很慢,因此做一些需要它反复预热的事情会使你的表现无效。
这里的解决方案当然是简单地将类定义移到被基准测试的代码之外。
答案 1 :(得分:8)
直接回答标题中的问题:__slots__
对于PyPy中的表现毫无意义(但不会造成伤害)。