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

发布于 2021-01-29 15:27:48

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

一个int类型的大小的28 bytes,当我不断增加的价值int,在增量的大小增加4 bytes

  1. 为什么28 bytes最初要低至任何值1

  2. 为什么增加4 bytes

PS:我在x86_64(64位计算机)上运行Python 3.5.2。我正在寻找有关(3.0+)解释器如何在如此庞大的数量上工作的任何指针/资源/ PEP。

说明大小的代码:

>>> 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
关注者
0
被浏览
309
1 个回答
  • 面试哥
    面试哥 2021-01-29
    为面试而生,有面试问题,就找面试哥。

    为什么28字节的初始值低至1

    我相信@bgusach完全回答了这一点;Python使用C结构来表示Python世界中的对象,包括ints的任何对象:

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

    PyObject_VAR_HEAD是一个宏,在展开时会在结构中添加另一个字段(该字段PyVarObject专门用于具有某种长度概念的对象),并且ob_digits是一个保存数字值的数组。锅炉板大小来自于结构,为小型
    大型Python号码。

    为什么增加4字节?

    因为,当创建更大的数字时,大小(以字节为单位)是sizeof(digit);的倍数。您可以看到,在_PyLong_New其中使用以下命令longobject执行新的内存分配PyObject_MALLOC

    /* Number of bytes needed is: offsetof(PyLongObject, ob_digit) +
       sizeof(digit)*size.  Previous incarnations of this code used
       sizeof(PyVarObject) instead of the offsetof, but this risks being
       incorrect in the presence of padding between the PyVarObject header
       and the digits. */
    if (size > (Py_ssize_t)MAX_LONG_DIGITS) {
        PyErr_SetString(PyExc_OverflowError,
                        "too many digits in integer");
        return NULL;
    }
    result = PyObject_MALLOC(offsetof(PyLongObject, ob_digit) +
                             size*sizeof(digit));
    

    offsetof(PyLongObject, ob_digit) 是与保持其值无关的长对象的“模板”(以字节为单位)。

    digit在头文件保持被定义struct _longobjecttypedefuint32

    typedef uint32_t digit;
    

    并且sizeof(uint32_t)4字节。这是当size参数to_PyLong_New增大时您将看到的大小(以字节为单位)增加的数量。


    当然,这就是CPython选择实现它的方式。这是一个实现细节,因此您不会在PEP中找到太多信息。如果您可以找到相应的线程:-),则python-
    dev邮件列表将包含实现讨论。

    无论哪种方式,您都可能在其他流行的实现中发现不同的行为,因此请不要认为这是理所当然的。



知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看