为什么相同长度的float32、float16类型numpy数组占用内存比float64更大?
现象原因
你观察到的反常识结果是由两个原因共同导致的:
sys.getsizeof()统计的是完整Python对象的内存占用,除了数组元素本身的存储空间,还包含numpy数组对象的固定元数据开销(存储数组维度、dtype、步长、内存地址等属性)。你测试用的数组只有8个元素,元数据开销的占比远高于元素本身的存储占比,会掩盖不同dtype的元素大小差异。- numpy针对不同dtype的数组内部会做内存对齐优化,不同dtype的元数据结构末尾的填充字节数不同,就出现了小dtype数组的总对象占用反而更高的情况。
你可以自己计算验证两者的开销拆分:
| 数组dtype | 8个元素本身占用 | sys.getsizeof返回总占用 | 元数据+填充开销 |
|---|---|---|---|
| float64 | 8*8=64字节 | 104字节 | 40字节 |
| float32 | 8*4=32字节 | 136字节 | 104字节 |
| float16 | 8*2=16字节 | 120字节 | 104字节 |
正确的数组元素内存统计方法
如果只需要统计数组元素本身占用的内存,直接调用numpy数组的nbytes属性即可,不会包含元数据开销:
import numpy as np a = np.linspace(0, 10, 8, dtype=np.float64) b = np.linspace(0, 10, 8, dtype=np.float32) c = np.linspace(0, 10, 8, dtype=np.float16) print(f'float64元素内存: {a.nbytes} bytes\nfloat32元素内存: {b.nbytes} bytes\nfloat16元素内存: {c.nbytes} bytes')
运行后会得到符合预期的结果:
float64元素内存: 64 bytes
float32元素内存: 32 bytes
float16元素内存: 16 bytes
当你测试的数组元素数量足够大时(比如10万+),元数据开销的占比可以忽略不计,此时即使用sys.getsizeof()统计,结果也会符合float16 < float32 < float64的规律。
内容的提问来源于stack exchange,提问作者BenjamnGC
相关产品推荐
相关产品推荐

