In-memory size of a Python structure In-memory size of a Python structure python python

In-memory size of a Python structure


The recommendation from an earlier question on this was to use sys.getsizeof(), quoting:

>>> import sys>>> x = 2>>> sys.getsizeof(x)14>>> sys.getsizeof(sys.getsizeof)32>>> sys.getsizeof('this')38>>> sys.getsizeof('this also')48

You could take this approach:

>>> import sys>>> import decimal>>> >>> d = {...     "int": 0,...     "float": 0.0,...     "dict": dict(),...     "set": set(),...     "tuple": tuple(),...     "list": list(),...     "str": "a",...     "unicode": u"a",...     "decimal": decimal.Decimal(0),...     "object": object(),... }>>> for k, v in sorted(d.iteritems()):...     print k, sys.getsizeof(v)...decimal 40dict 140float 16int 12list 36object 8set 116str 25tuple 28unicode 28

2012-09-30

python 2.7 (linux, 32-bit):

decimal 36dict 136float 16int 12list 32object 8set 112str 22tuple 24unicode 32

python 3.3 (linux, 32-bit)

decimal 52dict 144float 16int 14list 32object 8set 112str 26tuple 24unicode 26

2016-08-01

OSX, Python 2.7.10 (default, Oct 23 2015, 19:19:21) [GCC 4.2.1 Compatible Apple LLVM 7.0.0 (clang-700.0.59.5)] on darwin

decimal 80dict 280float 24int 24list 72object 16set 232str 38tuple 56unicode 52


These answers all collect shallow size information. I suspect that visitors to this question will end up here looking to answer the question, "How big is this complex object in memory?"

There's a great answer here: https://goshippo.com/blog/measure-real-size-any-python-object/

The punchline:

import sysdef get_size(obj, seen=None):    """Recursively finds size of objects"""    size = sys.getsizeof(obj)    if seen is None:        seen = set()    obj_id = id(obj)    if obj_id in seen:        return 0    # Important mark as seen *before* entering recursion to gracefully handle    # self-referential objects    seen.add(obj_id)    if isinstance(obj, dict):        size += sum([get_size(v, seen) for v in obj.values()])        size += sum([get_size(k, seen) for k in obj.keys()])    elif hasattr(obj, '__dict__'):        size += get_size(obj.__dict__, seen)    elif hasattr(obj, '__iter__') and not isinstance(obj, (str, bytes, bytearray)):        size += sum([get_size(i, seen) for i in obj])    return size

Used like so:

In [1]: get_size(1)Out[1]: 24In [2]: get_size([1])Out[2]: 104In [3]: get_size([[1]])Out[3]: 184

If you want to know Python's memory model more deeply, there's a great article here that has a similar "total size" snippet of code as part of a longer explanation: https://code.tutsplus.com/tutorials/understand-how-much-memory-your-python-objects-use--cms-25609


I've been happily using pympler for such tasks. It's compatible with many versions of Python -- the asizeof module in particular goes back to 2.2!

For example, using hughdbrown's example but with from pympler import asizeof at the start and print asizeof.asizeof(v) at the end, I see (system Python 2.5 on MacOSX 10.5):

$ python pymp.py set 120unicode 32tuple 32int 16decimal 152float 16list 40object 0dict 144str 32

Clearly there is some approximation here, but I've found it very useful for footprint analysis and tuning.