pympler: Wrong results when measuring object that uses __slots__?
Hello there, and thanks for Pympler!
While doing a few experiments on a class that uses __slots__ to reduce memory footprint I ran into a few unexpected results.
Testcase:
import sys
print(sys.version)
from pympler import asizeof
SLOTS = ("foo", "bar")
class Foo(object):
__slots__ = SLOTS
def __init__(self):
self.foo = SLOTS
self.bar = SLOTS
print(asizeof.asized(Foo(), detail=1).format())
print("Same object? " + str(Foo().__slots__ is SLOTS))
Results:
3.6.5 (default, Jun 20 2018, 09:33:17)
[GCC 5.4.0 20160609]
<__main__.Foo object at 0x7f143841ac88> size=304 flat=56
foo size=176 flat=64
__slots__ size=72 flat=72
__class__ size=0 flat=0
bar size=0 flat=0
Same object? True
Three things seem to be wrong in this case:
- the flat size of
__slots__is 8 bytes more than the object itself - the total size of the
Fooinstance does not account for the fact thatfooand__slots__are pointing at the same object - the flat size of
__slots__is shown to be the same as the size
Thus, whereas I would expect in this case the total size to be 56 + 176, pympler reports it as 56 + 176 + 72.
I was able to validate similar results with Python 2.7, so it doesn’t seem to be something that may be off in any specific version.
Is this a pympler bug, or am I missing some important detail on how __slots__ are actually implemented that causes this?
About this issue
- Original URL
- State: closed
- Created 6 years ago
- Comments: 19 (12 by maintainers)
Glad you mentioned Fluent Python, that answers the question where/how
__slots__instance values are stored.The tuple-like storage for
__slots__is part of the instance and the instance’basicsizealready includes the size of that tuple-like space.However, that also means, if the
__slots__of different instances have the exact same values, the tuple-like space for the individual__slots__is allocated in each instance.I’ll need to run a few more tests to the verify this and fix
asizeofaccordingly.