duncan at NOSPAMrcp.co.uk
Thu Sep 12 10:53:11 CEST 2002
steven_shaw at adc.com (Steven Shaw) wrote in
news:66715c02.0209111633.771aa9d3 at posting.google.com:
> Thanks alot for your time on this.
It was fun!
> I hadn't read about the __slots__
> mechanism before. I feel that there must be something wrong, though,
> because the Old object layout is winning! Maybe the implementation is
> finding the index of the variable in the __slots__ array and then>
> using returning __values__[index] in order to implement the attribute
> access. I made up the "__values__" array - there must be a values
> array somewhere. Array-based object layout amounts to the same thing
> as record-based-layout in Python because all primitives are the same
> size (right?). There needs to be a way for Python to remember the
> indexes... Hmmm. I think your test code doesn't allow the compiler to
> remember the indexes since it creates an instance anonymously (using
It is quite hard working out from the code what happens, but basically when
you define __slots__ it allocates space in the object to hold the actual
data for each slot, and makes a copy of the __slots__ list. It also creates
an object of type member_descriptor for each slot and stores it in the
class dictionary under the name of the slot.
__slots__ = ['a', 'b']
inst = C()
If you look at C.__dict__['a'] and C.__dict__['b'] they are
member_descriptor objects. Accessing inst.a therefore will call
C.a.__get__(inst, C) or C.a.__set__(inst, value). Each member_descriptor
object knows the offset where its data is stored.
So you still have the overhead of a dictionary lookup for every __slot__
access (although Python dictionary lookup is pretty fast), and you have
saved the overhead of a dictionary on every instance at the cost of an
extra object in the class for each attribute. It is slower than ordinary
attribute access because after the dictionary lookup instead of returning
the value that was found you have to call one of its methods (although
fortunately that doesn't involve another dictionary lookup, just a C call).
I hope this makes sense.
duncan at rcp.co.uk int month(char
"\6\7\xb\1\x9\xa\2\0\4"];} // Who said my code was obscure?
More information about the Python-list