python - Python 基本类型的内存使用(特别是 int 和 float)
问题描述
这是来自 Python 3.8.0 解释器的示例(但是,在 3.7.5 中类似)
>>> import sys
>>> sys.getsizeof(int)
416
>>> sys.getsizeof(float)
416
>>> sys.getsizeof(list)
416
>>> sys.getsizeof(tuple)
416
>>> sys.getsizeof(dict)
416
>>> sys.getsizeof(bool)
416
getsizeof()
返回 Python 对象消耗的字节数以及垃圾收集器开销(参见此处)。基本 python 类消耗相同数量的内存的原因是什么?
如果我们看一下这些类的实例
>>> import sys
>>> sys.getsizeof(int())
24
>>> sys.getsizeof(float())
24
默认参数是0
,并且这两个实例对此参数的内存使用量相同。但是,如果我尝试添加一个参数
>>> sys.getsizeof(int(1))
28
>>> sys.getsizeof(float(1))
24
这就是奇怪的地方。为什么 int 类型的实例内存使用量增加但 float 类型不增加?
解决方案
简而言之,这一切都归结为 Python 如何表示任意长整数。float()
类型的表示(受限)就像 C 一样double
。
在 CPython 实现中,每个对象(source)都以引用计数和指向该对象的类型对象的指针开始。那是 16 个字节。
浮点对象将其数据存储为 C double
( source ),即 8 个字节。所以浮点对象的 16 + 8 = 24 个字节。
使用整数,情况会更复杂。整数对象表示为可变大小的对象(source),对于 16 个字节,它又增加了 8 个字节。数字表示为数组。根据平台的不同,Python 使用具有 30 位数字的 32 位无符号整数数组或具有 15 位数字的 16 位无符号整数数组。所以对于小整数,数组中只有一个 32 位整数,所以再添加 4 bytes = 16 + 8 + 4 = 28 bytes。
如果要表示更大的整数,则大小会增长:
sys.getsizeof(int(2**32)) # prints 32 (24 + 2*4 bytes)
sys.getsizeof(int(2**64)) # prints 36 (24 + 3*4 bytes)
编辑:
随着sys.getsizeof(int)
您获得类的大小,而不是类的实例的大小。float
, bool
, ...也是一样
print(type(int)) # prints <class 'type'>
如果您查看源代码,则引擎盖下有很多东西。在我的 Python 3.6.9 (Linux/64bit) 版本中,这会打印 400 个字节。