Could someone explain what happens with the memory behind the scenes when manipulating with dictionary
and objects
in the following example :
In [52]: class O(object):
....: var1 = 'asdfasdfasfasdfasdfasdfasdf'
....: var2 = 255
....:
In [53]: dt = {'var1': 'asdfasdfasfasdfasdfasdfasdf', 'var2': 255}
In [55]: o = O()
In [57]: sys.getsizeof(o)
Out[57]: 64
In [58]: sys.getsizeof(dt)
Out[58]: 280
Next thing is weird according to above values
In [68]: sys.getsizeof(o.var1)
Out[68]: 64
In [69]: sys.getsizeof(o.var2)
Out[69]: 24
In [70]: sys.getsizeof(dt['var1'])
Out[70]: 64
In [71]: sys.getsizeof(dt['var2'])
Out[71]: 24
The values in data structures are the same size, but the difference between types makes me wonder what happens on behind the scenes?
Does the example makes objects
more effective over dictionaries
?
I use Ubuntu 14.04 and Python 2.7.6
Note that sys.getsizeof
gives you the size of the object itself, but that's not the whole story. An object has various attributes that also contribute to the overall memory footprint. For example, an instance of a class has a __dict__
, which holds the values of its attributes:
>>> o = O()
>>> o.__dict__
{}
>>> sys.getsizeof(o.__dict__)
140
Note three interesting things:
o.__dict__
, because var1
and var2
are class attributes, stored on O
, not instance attributes; ando.__dict__
, it's still the same size as dt
, because dictionaries are initialised with enough space for (IIRC) eight keys to avoid frequent resizing as you add items to them (for more information on the implementation of dictionaries, see "The Mighty Dictionary").Note also that if we compare the size of the instance plus the class in both cases, which is a fairer comparison, the gap narrows:
>>> sys.getsizeof(o) + sys.getsizeof(O)
484
>>> sys.getsizeof(dt) + sys.getsizeof(dict)
576
Does the example makes objects more effective over dictionaries?
Not at all; for one thing, as I've shown, objects are generally implemented using dictionaries (there is a way to not create a __dict__
for each instance, by defining __slots__
of pre-defined attributes on the class, but I won't get into that here) and dictionaries are objects in themselves (although the built-in types are slightly different for reasons I won't dwell on)!
In general, don't worry about the memory details unless it becomes a problem - define a class if you need state and behaviour (attributes and methods) and use a dictionary if you only need the state.