我想检查 python 中 int 数据类型的大小:
import sys
sys.getsizeof(int)
结果是“436”,这对我来说没有意义。无论如何,我想知道我的机器上有多少字节(2,4,..?) int 。
我想检查 python 中 int 数据类型的大小:
import sys
sys.getsizeof(int)
结果是“436”,这对我来说没有意义。无论如何,我想知道我的机器上有多少字节(2,4,..?) int 。
您得到的是类的大小,而不是类的实例。调用int
以获取实例的大小:
>>> sys.getsizeof(int())
24
如果那个尺寸看起来还是有点大,请记住 Python与in(例如)cint
非常不同。int
在 Python 中,anint
是一个成熟的对象。这意味着有额外的开销。
除了其他存储之外,每个 Python 对象都至少包含一个引用计数和对该对象类型的引用;在 64 位机器上,占用 16 个字节!内部int
结构(由标准 CPython 实现决定)也随着时间而改变,因此占用的额外存储量取决于您的版本。
int
关于Python 2 和 3 中对象的一些细节这是 Python 2 中的情况。(其中一些改编自Laurent Luce的博客文章)。整数对象表示为具有以下结构的内存块:
typedef struct {
PyObject_HEAD
long ob_ival;
} PyIntObject;
PyObject_HEAD
是定义引用计数和对象类型的存储的宏。文档中对其进行了一些详细的描述,并且可以在此答案中看到代码。
内存分配在大块中,因此每个新整数都没有分配瓶颈。该块的结构如下所示:
struct _intblock {
struct _intblock *next;
PyIntObject objects[N_INTOBJECTS];
};
typedef struct _intblock PyIntBlock;
这些一开始都是空的。然后,每次创建一个新整数时,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
在 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 中整数大小的可变性暗示它们可能更像可变长度类型(如列表)。事实上,事实证明这是真的。这是Python 3中对象的C定义:struct
int
struct _longobject {
PyObject_VAR_HEAD
digit ob_digit[1];
};
该定义附带的注释总结了 Python 3 的整数表示。零不是由存储的值表示,而是由大小为零的对象表示(这就是为什么sys.getsizeof(0)
is 24
bytes 而sys.getsizeof(1)
is 28
)。负数由具有负大小属性的对象表示!太奇怪了。