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 Foo instance does not account for the fact that foo and __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)

Most upvoted comments

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’ basicsize already 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 asizeof accordingly.