Avez-vous essayé d'utiliser __slots__
?
À partir de la documentation http://docs.python.org/reference/datamodel.html#slots:
"Par défaut, les instances de l'ancien et du nouveau style de classes ont un dictionnaire pour le stockage des attributs. Cela gaspille de l'espace pour les objets ayant très peu de variables d'instance. La consommation de l'espace peut devenir aiguë lors de la création d'un grand nombre de cas.
La valeur par défaut peut être remplacée par la définition d' __slots__
dans un nouveau style de la définition de la classe. L' __slots__
déclaration prend une séquence de variables d'instance et les réserves de juste assez d'espace dans chaque cas pour contenir une valeur pour chaque variable. L'espace est sauvé parce qu' __dict__
n'est pas créé pour chaque instance."
Donc, cela permet d'économiser du temps, de la mémoire?
En comparant les trois approches sur mon ordinateur:
test_slots.py:
class Obj(object):
__slots__ = ('i', 'l')
def __init__(self, i):
self.i = i
self.l = []
all = {}
for i in range(1000000):
all[i] = Obj(i)
test_obj.py:
class Obj(object):
def __init__(self, i):
self.i = i
self.l = []
all = {}
for i in range(1000000):
all[i] = Obj(i)
test_dict.py:
all = {}
for i in range(1000000):
o = {}
o['i'] = i
o['l'] = []
all[i] = o
test_namedtuple.py (pris en charge dans 2.6):
import collections
Obj = collections.namedtuple('Obj', 'i l')
all = {}
for i in range(1000000):
all[i] = Obj(i, [])
Référence (à l'aide de Disponible 2.5):
$ lshw | grep product | head -n 1
product: Intel(R) Pentium(R) M processor 1.60GHz
$ python --version
Python 2.5
$ time python test_obj.py && time python test_dict.py && time python test_slots.py
real 0m27.398s (using 'normal' object)
real 0m16.747s (using __dict__)
real 0m11.777s (using __slots__)
L'aide Disponible 2.6.2, y compris le nom de n-uplet de test:
$ python --version
Python 2.6.2
$ time python test_obj.py && time python test_dict.py && time python test_slots.py && time python test_namedtuple.py
real 0m27.197s (using 'normal' object)
real 0m17.657s (using __dict__)
real 0m12.249s (using __slots__)
real 0m12.262s (using namedtuple)
Donc, oui (pas vraiment une surprise), à l'aide de __slots__
est une optimisation des performances. À l'aide d'un nommé n-uplet a des performances similaires à l' __slots__
.