Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/vim/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python &引用;sys.getsizeof(int)";返回一个不合理的大值?_Python - Fatal编程技术网

Python &引用;sys.getsizeof(int)";返回一个不合理的大值?

Python &引用;sys.getsizeof(int)";返回一个不合理的大值?,python,Python,我想检查python中int数据类型的大小: import sys sys.getsizeof(int) 结果是“436”,这对我来说毫无意义。 无论如何,我想知道我的机器将占用多少字节(2,4,…?)int。简短答案 您得到的是类的大小,而不是类的实例的大小。调用int获取实例的大小: >>> sys.getsizeof(int()) 24 如果这个大小看起来仍然有点大,请记住Pythonint与(例如)c中的int非常不同。在Python中,int是一个成熟的对象。这意

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

import sys
sys.getsizeof(int)
结果是“436”,这对我来说毫无意义。 无论如何,我想知道我的机器将占用多少字节(2,4,…?)int。

简短答案 您得到的是类的大小,而不是类的实例的大小。调用
int
获取实例的大小:

>>> sys.getsizeof(int())
24
如果这个大小看起来仍然有点大,请记住Python
int
与(例如)c中的
int
非常不同。在Python中,
int
是一个成熟的对象。这意味着有额外的开销

除了其他存储之外,每个Python对象至少包含一个refcount和一个对对象类型的引用;在64位机器上,这将占用16个字节!
int
内部(由标准CPython实现确定)也随着时间的推移而改变,因此占用的额外存储量取决于您的版本

关于Python2和Python3中
int
对象的一些详细信息 下面是Python 2中的情况。(其中一些内容改编自作者的博客文章)。整数对象表示为具有以下结构的内存块:

typedef struct {
    PyObject_HEAD
    long ob_ival;
} PyIntObject;
PyObject\u HEAD
是定义refcount和对象类型存储的宏。它由描述了一些细节,代码可以在答案中看到

内存是在大的块中分配的,因此对于每个新的整数没有分配瓶颈。块的结构如下所示:

struct _intblock {
    struct _intblock *next;
    PyIntObject objects[N_INTOBJECTS];
};
typedef struct _intblock PyIntBlock;
这些一开始都是空的。然后,每次创建一个新的整数时,Python都会使用
next
指向的内存,并递增
next
以指向块中的下一个自由整数对象

我不完全确定,一旦超过普通整数的存储容量,这会发生什么变化,但一旦超过了,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

Python3中整数大小的可变性暗示它们的行为可能更像可变长度类型(如列表)。事实证明,这是真的。下面是Python 3中for
int
对象的定义:

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

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

请注意,python支持非常大的数字,这意味着您几乎肯定不会得到2或4或更接近的数字。你到底想干什么?确定您运行的是32位还是64位OS/CPU?谢谢!但我的系统返回12的大小。以字节为单位吗?如果以字节为单位,比我想象的要大,如果以位为单位,则不合理…@HailiangZhang,这是12个字节——在我的例子中是24个字节。Python int与(例如)c中的int非常不同。在Python中,
int
是一个成熟的对象。这意味着有额外的开销。有关(cpython)
int
内部结构的详细讨论,请参阅。@HailiangZhang还描述了您在上面链接的页面中看到的
PyObject\u HEAD
宏的结构。除其他存储外,每个Python对象至少包含一个refcount和对对象类型的引用。如果要存储大量紧凑存储的32位(或更少位)整数,请参阅
数组
模块。请注意,0的结果仅为24(这是int()返回的值)。尝试
sys.getsizeof(1)
,您将得到28。