简体   繁体   English

在PyPy下使用__slots__

[英]Using __slots__ under PyPy

I have this simple code that helped me to measure how classes with __slots__ perform (taken from here ): 我有一个简单的代码,可以帮助我衡量带有__slots__类的性能(从此处获取 ):

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)

If I run it via python2.7 - I would get something around 6 seconds - ok, it's really faster (and also more memory-efficient) than without slots. 如果我通过python2.7运行它-我会在6秒钟左右得到一些结果-好的,它比没有插槽的速度更快(而且内存效率更高)。

But, if I run the code under PyPy (using 2.2.1 - 64bit for Mac OS/X), it starts to use 100% CPU and "never" returns (waited for minutes - no result). 但是,如果我在PyPy下运行代码(对于Mac OS / X,使用2.2.1-64位),它将开始使用100%CPU,并且“从不”返回(等待数分钟-没有结果)。

What is going on? 到底是怎么回事? Should I use __slots__ under PyPy? 我应该在PyPy下使用__slots__吗?

Here's what happens if I pass different number to timeit() : 如果我将不同的数字传递给timeit()将会发生以下情况:

timeit(10) - 0.067s
timeit(100) - 0.5s
timeit(1000) - 19.5s
timeit(10000) - ? (probably more than a Game of Thrones episode)

Thanks in advance. 提前致谢。


Note that the same behavior is observed if I use namedtuple s: 请注意,如果使用namedtuple则会观察到相同的行为:

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)

In each of the 10,000 or so iterations of the timeit code, the class is recreated from scratch. timeit代码的timeit 10,000次迭代中的每个迭代中,都从头开始重新创建该类。 Creating classes is probably not a well-optimized operation in PyPy; 在PyPy中创建类可能不是一个优化的操作。 even worse, doing so will probably discard all of the optimizations that the JIT learned about the previous incarnation of the class. 甚至更糟的是,这样做可能会放弃JIT从该类的先前化身中学到的所有优化。 PyPy tends to be slow until the JIT has warmed up, so doing things that require it to warm up repeatedly will kill your performance. 在JIT进行热身之前,PyPy往往会变慢,因此重复执行需要它进行热身的操作会降低您的性能。

The solution here is, of course, to simply move the class definition outside of the code being benchmarked. 当然,这里的解决方案是将类定义简单地移到被基准测试的代码之外。

要直接回答标题中的问题: __slots__对于PyPy的性能毫无意义(但不会影响)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM