Вопрос по python – «Sys.getsizeof (int)» возвращает неоправданно большое значение?

27

Я хочу проверить размер типа данных int в Python:

<code>import sys
sys.getsizeof(int)
</code>

Получается, что это «436», что не имеет смысла для меня. В любом случае, я хочу знать, сколько байтов (2,4, ..?) Int займет на моей машине.

Обратите внимание, что в python есть поддержка очень больших чисел, что означает, что вы почти наверняка не получите 2 или 4 или что-то даже близко. Что ты такоеreally пытаешься сделать? Выясните, используете ли вы 32-битную или 64-битную ОС / ЦП? Lasse Vågsæther Karlsen

Ваш Ответ

1   ответ
59

The short answer

Вы получаете размерclass, а не экземпляра класса. Вызовint чтобы получить размер экземпляра:

>>> sys.getsizeof(int())
24

Если этот размер все еще кажется немного большим, помните, что Pythonint сильно отличается отint в (например) в. В Pythonint является полноценным объектом. Это означает, что есть дополнительные накладные расходы.

Каждый объект Python содержит, по меньшей мере, ссылку и ссылку на тип объекта в дополнение к другому хранилищу; на 64-битной машине это занимает 16 байтов!int внутренние компоненты (как определено стандартной реализацией CPython) также со временем менялись, поэтому объем занимаемой дополнительной памяти зависит от вашей версии.

Some details about int objects in Python 2 and 3

Вот ситуация в Python 2. (Часть этого адаптирована из сообщения в блогеЛоран Люс). Целочисленные объекты представлены в виде блоков памяти со следующей структурой:

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 является намеком на то, что они могут вести себя больше как типы переменной длины (например, списки). И действительно, это оказывается правдой. Вот определениеСstruct заint объекты в Python 3:

struct _longobject {
    PyObject_VAR_HEAD
    digit ob_digit[1];
};

Комментарии которые сопровождают это определение, суммируют представление целых чисел в Python 3. Ноль представлен не сохраненным значением, а объектом с нулевым размером (вот почемуsys.getsizeof(0) является24 байт в то время какsys.getsizeof(1) является28). Отрицательные числа представлены объектами с отрицательным атрибутом размера! Так странно.

Error: User Rate Limit Exceeded Hailiang Zhang
Error: User Rate Limit ExceededintError: User Rate Limit ExceededhereError: User Rate Limit ExceededintError: User Rate Limit Exceeded
Error: User Rate Limit Exceededsys.getsizeof(1)Error: User Rate Limit Exceeded
Error: User Rate Limit ExceededarrayError: User Rate Limit Exceeded
Error: User Rate Limit ExceededthisError: User Rate Limit ExceededPyObject_HEADError: User Rate Limit Exceeded

Похожие вопросы