Blog Entry
Python __slots__
From the Python documentation:
By default, instances of both old and new-style classes have a dictionary for attribute storage. This wastes space for objects having very few instance variables. The space consumption can become acute when creating large numbers of instances. The default can be overridden by defining __slots__ in a new-style class definition. The __slots__ declaration takes a sequence of instance variables and reserves just enough space in each instance to hold a value for each variable. Space is saved because __dict__ is not created for each instance.To test this I created two dummy classes, one with the
__slots__ tuple attribute and one without it. Then I compared the instantiation time for the two classes with timeit and did some memory profiling with heapy.
### Code Start ###
import timeit
from guppy import hpy
class Foo(object):
def __init__(self):
self.x = 1
self.y = 2
class FooSlots(object):
__slots__ = ('x', 'y')
def __init__(self):
self.x = 1
self.y = 2
# test speed...
passes = 1000
print 'Number of instantiations:', passes
t = timeit.Timer('Foo( )', 'from __main__ import Foo')
print 'Foo class instantiation times:', t.timeit(passes)
t = timeit.Timer('FooSlots( )', 'from __main__ import FooSlots')
print 'FooSlots class instantiation times:', t.timeit(passes)
## test memory...
hp = hpy( )
hp.setrelheap( )
class_count = 1000
l = [FooSlots( ) for i in range(class_count)]
h = hp.heap( )
print h
hp.setrelheap( )
l = [Foo( ) for i in range(class_count)]
h = hp.heap( )
print h
### Code End ###
The result of running the tests show that there is not a big difference in instantiation times, but there is a substantial memory saving:
Number of instantiations: 1000
Foo class instantiation times: 0.00138711929321
FooSlots class instantiation times: 0.00114798545837
Partition of a set of 1003 objects. Total size = 32588 bytes.
Index Count % Size % Cumulative % Kind (class / dict of class)
0 1000 100 28000 86 28000 86 __main__.FooSlots
1 1 0 4128 13 32128 99 list
2 1 0 448 1 32576 100 types.FrameType
3 1 0 12 0 32588 100 int
Partition of a set of 2003 objects. Total size = 168540 bytes.
Index Count % Size % Cumulative % Kind (class / dict of class)
0 1000 50 136000 81 136000 81 dict of __main__.Foo
1 1000 50 28000 17 164000 97 __main__.Foo
2 1 0 4128 2 168128 100 list
3 1 0 400 0 168528 100 types.FrameType
4 1 0 12 0 168540 100 int
- Posted on:
- 2010.01.14 -0600
- Tags:
- code
víctor adán