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

时间:2016-10-31 14:25:37

标签: python python-3.x int python-internals

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

int类型的大小为28 bytes,随着我不断增加int的值,大小会以4 bytes的增量增加。

  1. 为什么28 bytes最初的价值低至1

  2. 为什么增加4 bytes

  3. 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
    

2 个答案:

答案 0 :(得分:25)

  

为什么28字节最初的任何值都低至1

我完全相信@bgusach answered that; Python使用C结构来表示Python世界中的对象,任何对象including 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 _longobject在头文件中定义,typedefuint32的{​​{1}}:

typedef uint32_t digit;

sizeof(uint32_t)4个字节。当size _PyLong_New参数增加时,您查看大小(以字节为单位)的数量会增加。

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

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

答案 1 :(得分:16)

实际上很容易。 Python int不是你可能习惯于其他语言的原始类型,而是一个完整的对象,它的方法和所有东西。这就是开销来自的地方。

然后,您拥有有效负载本身,即正在表示的整数。除了你的记忆之外,没有限制。

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

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

  

整数具有无限精度