"sys.getsizeof(int)"返回一个不合理的大值?

Hai*_*ang 36 python

我想在python中检查int数据类型的大小:

import sys
sys.getsizeof(int)
Run Code Online (Sandbox Code Playgroud)

它出来是"436",这对我来说没有意义.无论如何,我想知道在我的机器上将占用多少字节(2,4,...?)int.

sen*_*rle 78

简短的回答

你得到的是班级的大小,而不是班级的实例.调用int以获取实例的大小:

>>> sys.getsizeof(int())
24
Run Code Online (Sandbox Code Playgroud)

如果这个大小看起来仍然有点大,请记住Python intintin(例如)c 非常不同.在Python中,a int是一个完全成熟的对象.这意味着需要额外的开销.

除了其他存储之外,每个Python对象至少包含一个引用计数和对象类型的引用; 在64位机器上,占用16个字节!该int内部(由标准CPython的实现来确定)也随时间而变化,从而使采取额外的存储量取决于您的版本.

有关intPython 2和3中对象的一些细节

这是Python 2中的情况.(其中一些改编自Laurent Luce的博客文章).整数对象表示为具有以下结构的内存块:

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

PyObject_HEAD是一个定义refcount和对象类型的存储的宏.它由文档详细描述,代码可以在这个答案中看到.

内存以大块分配,因此每个新整数都没有分配瓶颈.块的结构如下所示:

struct _intblock {
    struct _intblock *next;
    PyIntObject objects[N_INTOBJECTS];
};
typedef struct _intblock PyIntBlock;
Run Code Online (Sandbox Code Playgroud)

这些都是空的.然后,每次创建一个新整数时,Python使用指向的内存next和增量next指向块中的下一个空闲整数对象.

一旦超过普通整数的存储容量,我不完全确定这会如何变化,但一旦这样做,a的大小int就会变大.在我的机器上,在Python 2中:

>>> sys.getsizeof(0)
24
>>> sys.getsizeof(1)
24
>>> sys.getsizeof(2 ** 62)
24
>>> sys.getsizeof(2 ** 63)
36
Run Code Online (Sandbox Code Playgroud)

在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
Run Code Online (Sandbox Code Playgroud)

当然,这些结果都依赖于硬件!因人而异.

Python 3中整数大小的可变性暗示它们可能更像是可变长度类型(如列表).事实上,事实证明这是真的.这里的定义Çstruct用于int在Python 3对象:

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

此定义附带的注释总结了Python 3的整数表示.零被存储的值不表示,但通过用零大小的对象(这就是为什么sys.getsizeof(0)24字节,而sys.getsizeof(1)28).负数由具有负大小属性的对象表示!太奇怪了.

  • @HailangZhang,这是 12 个字节——在我的例子中是 24 个字节。Python int 与(例如)c 中的 int 非常不同。在 Python 中,`int` 是一个成熟的对象。这意味着有额外的开销。请参阅 [此处](http://www.laurentluce.com/posts/python-integer-objects-implementation/) 以获取有关 (cpython) `int` 内部结构的相当详细的讨论。 (2认同)
  • @HailiangZhang,另外,[这](http://docs.python.org/c-api/structures.html)描述了你链接到网页上面看到`PyObject_HEAD`宏观的结构.除了其他存储之外,每个Python对象至少包含一个引用计数和对象类型的引用. (2认同)
  • 如果要存储大量紧凑存储的 32 位(或更少位)整数,请参阅 `array` 模块。 (2认同)