Я хочу проверить размер типа данных int в python:
import sys
sys.getsizeof(int)
Это выходит за "436", что для меня не имеет смысла. Во всяком случае, я хочу знать, сколько байтов (2,4,...?) Int будет использоваться на моей машине.
Я хочу проверить размер типа данных int в python:
import sys
sys.getsizeof(int)
Это выходит за "436", что для меня не имеет смысла. Во всяком случае, я хочу знать, сколько байтов (2,4,...?) Int будет использоваться на моей машине.
Вы получаете размер класса, а не экземпляр класса. Вызовите int
, чтобы получить размер экземпляра:
>>> sys.getsizeof(int())
24
Если этот размер по-прежнему кажется немного большим, помните, что Python int
сильно отличается от int
в (например) c. В Python объект int
является полнофункциональным. Это означает дополнительные накладные расходы.
Каждый объект Python содержит по крайней мере refcount и ссылку на тип объекта в дополнение к другому хранилищу; на 64-битной машине, которая занимает 16 байтов! Внутренние элементы int
(как определено стандартной реализацией CPython) также со временем изменились, поэтому количество дополнительного хранилища зависит от вашей версии.
int
в Python 2 и 3Здесь ситуация в Python 2. (Некоторые из них адаптированы из сообщения в блоге Laurent Luce). Целочисленные объекты представляются в виде блоков памяти со следующей структурой:
typedef struct {
PyObject_HEAD
long ob_ival;
} PyIntObject;
PyObject_HEAD
- это макрос, определяющий хранилище для refcount и тип объекта. Он подробно описан в документации , и этот код можно увидеть в этом ответ.
Память выделяется большими блоками, так что не будет узкого места для каждого нового целого. Структура блока выглядит следующим образом:
struct _intblock {
struct _intblock *next;
PyIntObject objects[N_INTOBJECTS];
};
typedef struct _intblock PyIntBlock;
Все сначала пустые. Затем каждый раз, когда создается новое целое число, Python использует память, на которую указывает next
, и увеличивает next
, чтобы указать на следующий свободный целочисленный объект в блоке.
Я не совсем уверен, как это изменится, если вы превысите емкость хранилища обычного числа, но как только вы это сделаете, размер int
станет больше. На моей машине, в Python 2:
>>> sys.getsizeof(0)
24
>>> sys.getsizeof(1)
24
>>> sys.getsizeof(2 ** 62)
24
>>> sys.getsizeof(2 ** 63)
36
В Python 3 я думаю, что общая картина такая же, но размер целых чисел увеличивается по частям:
>>> sys.getsizeof(0)
24
>>> sys.getsizeof(1)
28
>>> sys.getsizeof(2 ** 30 - 1)
28
>>> sys.getsizeof(2 ** 30)
32
>>> sys.getsizeof(2 ** 60 - 1)
32
>>> sys.getsizeof(2 ** 60)
36
Эти результаты, конечно же, зависят от оборудования! YMMV.
Изменчивость целочисленного размера в Python 3 - это намек на то, что они могут вести себя как типы переменной длины (например, списки). И действительно, это оказывается правдой. Здесь определение C struct
для объектов int
в Python 3:
struct _longobject {
PyObject_VAR_HEAD
digit ob_digit[1];
};
комментарии, которые сопровождают это определение, суммируют представление Python 3 целых чисел. Ноль представлен не хранимым значением, а объектом с нулевым размером (поэтому sys.getsizeof(0)
- это 24
байты, а sys.getsizeof(1)
- 28
). Отрицательные числа представлены объектами с атрибутом отрицательного размера! Настолько странно.