为什么int需要三倍于Python的内存?

jak*_*rbo 25 python memory int object python-internals

在64位系统上,Python中的整数需要24个字节.这是例如C对于64位整数所需的内存的3倍.现在,我知道这是因为Python整数是对象.但是用于什么额外的内存?我有猜测,但肯定知道这会很好.

Mar*_*ers 33

请记住,Python int类型没有像C一样的有限范围int; 唯一的限制是可用内存.

内存用于存储值,整数存储的当前大小(存储大小可变以支持任意大小),以及标准Python对象簿记(对相关对象的引用和引用计数).

你可以查找longintrepr.h源代码(Python 3 int类型传统上称为longPython 2中的类型); 它有效地使用PyVarObjectC类型来跟踪整数大小:

struct _longobject {
        PyObject_VAR_HEAD
        digit ob_digit[1];
};
Run Code Online (Sandbox Code Playgroud)

ob_digit数组存储15或30位宽的"数字"(取决于您的平台); 所以在我的64位OS X系统上,最多(2 ^ 30)-1的整数使用1'数字':

>>> sys.getsizeof((1 << 30) - 1)
28
Run Code Online (Sandbox Code Playgroud)

但如果您在数字中使用2个30位数字,则需要额外的4个字节,等等:

>>> sys.getsizeof(1 << 30)
32
>>> sys.getsizeof(1 << 60)
36
>>> sys.getsizeof(1 << 90)
40
Run Code Online (Sandbox Code Playgroud)

然后,基本24字节是PyObject_VAR_HEAD结构,保持对象大小,引用计数和类型指针(在我的64位OS X平台上每8字节/ 64位).

在Python 2上,整数<= sys.maxintbut> = -sys.maxint - 1使用更简单的结构存储,只存储单个值:

typedef struct {
    PyObject_HEAD
    long ob_ival;
} PyIntObject;
Run Code Online (Sandbox Code Playgroud)

因为这使用PyObject而不是结构中PyVarObject没有ob_size字段,并且内存大小仅限于24个字节; 8表示long值,8表示引用计数,8表示类型对象指针.

  • @Har:完全正确;内部表示不使用 2 补码。 (2认同)