>>> import sys
>>> sys.getsizeof(123456)
28
Это 7 размер C int
. В Python 3 целые числа являются экземплярами struct _longobject
a.k.a PyLong
:
struct _longobject {
PyVarObject ob_base;
digit ob_digit[1];
};
, где PyVarObject
равно
typedef struct {
PyObject ob_base;
Py_ssize_t ob_size;
} PyVarObject;
и PyObject
- это
typedef struct _object {
Py_ssize_t ob_refcnt;
struct _typeobject *ob_type;
} PyObject;
Отсюда мы получаем следующее использование памяти для этого объекта 123456 в 64-битной сборке Python:
- 8 байтов для счетчика ссылок (
Py_ssize_t
)
- 8 байт для указателя на тип объекта
&PyLong_Type
(типа PyTypeObject *
- 8 байтов для подсчета количества байтов в части переменной длины объекта; (типа
Py_ssize_t
)
- 4 байта на каждые 30 бит цифр в целом числе.
Поскольку 123456 помещается в первые 30 битов, это сумма до 28, или 7 * sizeof (int)
Это в дополнение к тому факту, что каждый элемент в Python list
является PyObject *
, который указывает на реальный объект; каждый из этих указателей является 64-битным в 64-битных сборках Python; это означает, что каждая ссылка на элемент списка в отдельности потребляет вдвое больше памяти, чем C int
.
Сложите 7 и 2, и вы получите 9 .
Для более эффективного хранения кода вы можете использовать массивы ; с кодом типа 'i'
потребление памяти должно быть достаточно близко к версии C. У array
s есть метод append
, благодаря которому увеличение массива должно быть даже проще, чем в C / с realloc
.