0

Why is the memory allocation for a list x numbers less than the memory allocation of its combined elements? intA is an integer value of 10, requiring 28bytes for storage. However, List A contains 10 integers and requires 184bytes? What is the reasoning for this? I would have suspected the memory allocation would be greater that 10 times the bytes requires for a single integer, considering the list data structure is also required to be stored in memory, in addition to the pointers and lastly their integer object values. Unless it describes the memory allocation for the List structure only. Any clarifications? Thanks

intA = 10
A = [x for x in range(0,10)]
print(getsizeof(intA), getsizeof(A))

Output: 28 184

  • I'm no expert in memory management in python, but I see no reason to assume no overhead for storing a single int, thus I would not expect the object size of a list of 10 ints (with only 1 overhead for the list) to be necessarily more than 10x a single int (with 10x overheads for each int), – Julien Jun 06 '22 at 00:56
  • 1
    Does this answer your question? [How do I determine the size of an object in Python?](https://stackoverflow.com/questions/449560/how-do-i-determine-the-size-of-an-object-in-python). The answers there should explain how the output of getsizeof should be interpreted. TL;DR: getsizeof reports a guess about the size of a _single_ object. It doesn't consider the other objects that an object may hold reference to, like the entries in a list – Brian61354270 Jun 06 '22 at 01:01
  • 1
    _"Unless it describes the memory allocation for the List structure only."_ It does. – Brian61354270 Jun 06 '22 at 01:06

1 Answers1

1

You can check the implementation of list.__sizeof__:

_PyObject_SIZE(Py_TYPE(self)) + self->allocated * sizeof(void*);

Here's the breakdown:

  • _PyObject_SIZE(Py_TYPE(self)): this is the overhead that every list carries: it needs a reference count, it needs to store its logical size len(x), and it needs to show how much allocated room it can use before allocating more memory, and it needs a pointer to its type, list, and it needs to store the pointer to its current buffer.

  • sizeof(void*): Note that lists always store pointers, never actual machine integers directly.

  • self->allocated: This is how large the list's ob_item buffer currently is.

In particular, note that this computation is not recursive; it is "shallow". __sizeof__ methods generally only describe how much room they take unto themselves, not including any objects they contain

Dennis
  • 2,249
  • 6
  • 12