【问题标题】:Memory usage of Python base types (particulary int and float)Python 基本类型的内存使用(特别是 int 和 float)
【发布时间】:2019-12-15 09:25:32
【问题描述】:

这是来自 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 对象消耗的字节数以及垃圾收集器开销(请参阅here)。基本的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 != C 。 getsizeof(some_type) 为您提供 类型对象本身 的大小,而不是该类型的实例。试试getsizeof(1); getsizeof(1.0); getsizeof([])

标签: python memory-management python-internals


【解决方案1】:

简而言之,这一切都归结为 Python 如何表示任意长整数。 float() 类型的表示(有限)就像 C double

在 CPython 实现中,每个对象 (source) 都以引用计数和指向该对象的类型对象的指针开始。那是 16 个字节。

Float 对象将其数据存储为 C double (source),即 8 个字节。所以 16 + 8 = 24 字节 用于浮点对象。

使用整数,情况会更复杂。整数对象表示为可变大小的对象 (source),对于 16 个字节,它又增加了 8 个字节。 数字表示为数组。根据平台的不同,Python 使用具有 30 位数字的 32 位无符号整数数组或具有 15 位数字的 16 位无符号整数数组。所以对于小整数,数组中只有一个 32 位整数,所以再添加 4 字节 = 16 + 8 + 4 = 28 字节

如果要表示更大的整数,大小会变大:

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'>

如果您查看source,就会发现引擎盖下有很多东西。在我的 Python 3.6.9 (Linux/64bit) 版本中,这会打印 400 个字节。

【讨论】:

  • 这是一个很好的解释,谢谢!您能否提供第一个关于班级规模的问题的答案,以便您的答案在被接受之前完整?
  • @vezeli 我添加了关于类型对象大小的解释。
  • 剩余 2 位如何使用(“32 位无符号整数数组,30 位数字”)?
【解决方案2】:

看看the docs,重要的是要注意:

只考虑直接归因于对象的内存消耗,而不考虑它所引用的对象的内存消耗。

那么从sys.getsizeof(int(1)) 的返回值大于sys.getsizeof(float(1)) 的返回值这一事实你能推断出什么?

简单地说,表示int 比表示float 需要更多的内存。这令人惊讶吗?好吧,可能不会,如果我们可以期望使用int 比使用float 可以“做更多的事情”。我们可以通过查看它们的属性数量来衡量“功能的数量”:

>>> len(dir(int))
70
>>> len(dir(float))
57

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-05-25
    • 2019-02-24
    • 1970-01-01
    • 2016-03-19
    • 2021-11-28
    相关资源
    最近更新 更多