ho questo semplice codice che mi ha aiutato a misurare quanto classi con __slots__
eseguire (tratto da here):Utilizzando __slots__ sotto PyPy
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)
Se l'eseguo via python2.7 - vorrei avere qualcosa di circa 6 secondi - ok, è molto più veloce (e anche più efficiente in termini di memoria) che senza slot.
Tuttavia, se eseguo il codice in PyPy (utilizzando 2.2.1 - 64 bit per Mac OS/X), inizia a utilizzare il 100% della CPU e "mai" restituisce (atteso per minuti - nessun risultato).
Cosa sta succedendo? Dovrei usare __slots__
sotto PyPy?
Ecco cosa succede se passo diverso numero di timeit()
:
timeit(10) - 0.067s
timeit(100) - 0.5s
timeit(1000) - 19.5s
timeit(10000) - ? (probably more than a Game of Thrones episode)
Grazie in anticipo.
Si noti che lo stesso comportamento si osserva se uso 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)
Indipendentemente da qualsiasi altra cosa, un programma che esegue un ciclo infinito o che richiede 60x finché sotto CPython è un bug e deve essere generato con i ragazzi di PyPy. – delnan
Mi aspetterei che la versione '__slots__' sia più lenta in quanto tali classi sono ottimizzate per lo spazio e non sono ottimizzate per il recupero degli attributi. – wheaties
@wheaties yup, ma il benchmark mostra che 'slots' e' namedtuples' sono anche più veloci: http://stackoverflow.com/questions/1336791/dictionary-vs-object-which-is-more-efficient-and-why/1336890 # 1336890 – alecxe