理解Python中大整数的内存分配

2024-09-24 02:19:30 发布

您现在位置:Python中文网/ 问答频道 /正文

Python如何为大整数分配内存?在

一个int类型的大小是28 bytes,当我不断增加int的值时,大小以4 bytes为增量增加。在

  1. 为什么28 bytes初始值为1那么低?

  2. 为什么增加4 bytes

PS:我在x86u64(64位机器)上运行Python3.5.2。关于(3.0以上)解释程序如何处理如此巨大的数字的任何建议/资源/政治公众人物都是我要找的。在

说明尺寸的代码:

>>> a=1
>>> print(a.__sizeof__())
28
>>> a=1024
>>> print(a.__sizeof__())
28
>>> a=1024*1024*1024
>>> print(a.__sizeof__())
32
>>> a=1024*1024*1024*1024
>>> print(a.__sizeof__())
32
>>> a=1024*1024*1024*1024*1024*1024
>>> a
1152921504606846976
>>> print(a.__sizeof__())
36

Tags: 机器类型bytes数字整数资源增量建议
2条回答

Why 28 bytes initially for any value as low as 1?

我完全相信@bgusach answered that;Python使用C结构来表示Python世界中的对象,任何对象including ^{}s

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

^{}是一个宏,它在展开时在结构中添加另一个字段(字段^{},它专门用于具有某种长度概念的对象),并且,^{}是一个保存数字值的数组。Boiler-plate的大小来自于这个结构,对于小的大的Python数。在

Why increments of 4 bytes?

因为,当创建一个更大的数字时,大小(以字节为单位)是sizeof(digit)的倍数;在^{}中,为新的{}分配内存是用PyObject_MALLOC执行的:

^{pr2}$

offsetof(PyLongObject, ob_digit)是与保持其值无关的长对象的“boiler plate”(字节)。

在包含struct _longobject的头文件中,digit被定义为uint32typedef

typedef uint32_t digit;

sizeof(uint32_t)4字节。这就是当_PyLong_Newsize参数增加时,以字节为单位的大小增加的量。在


当然,这正是CPython选择实现它的方式。这是一个实现细节,因此您不会在政治公众人物中找到太多信息。如果可以找到对应的线程:-),python dev邮件列表将举行实现讨论。在

不管怎样,您可能会在其他流行的实现中发现不同的行为,所以不要认为这是理所当然的。在

其实很简单。Python的int不是您可能会习惯于其他语言的那种原语,而是一个完整的对象,包括它的方法和所有的东西。这就是间接费用的来源。在

然后,就有了有效负载本身,即所表示的整数。这是没有限制的,除了你的记忆力。在

Python的int的大小就是它需要表示的数字加上一点开销。在

如果要进一步阅读,请查看relevant part of the documentation

Integers have unlimited precision

相关问题 更多 >