sys.getsizeof 是如何工作的?

How sys.getsizeof works underneath the hood?

我一直在检查函数 sys.getsizeof,并且我知道这个 returns 正在传递的参数的大小(以字节为单位)。

我有一些使用 C 的经验,我可以在知道某些类型的大小的情况下计算出某些值的大小。我已经 运行 对此功能进行了一些实验。

注意: 我在 macOS 上使用 Python 3.7.3 来 运行 以下内容:

对于数字

>>> sys.getsizeof(0)
24
>>> sys.getsizeof(1)
28
>>> sys.getsizeof(-1)
28
>>> sys.getsizeof(1.0)
24
>>> sys.getsizeof(-1.0)
24

对于列表

>>> sys.getsizeof([])
64
>>> sys.getsizeof([1])
72
>>> sys.getsizeof([1.0])
72
>>> sys.getsizeof([0, 1])
80

对于字符串

>>> sys.getsizeof('d')
50
>>> sys.getsizeof('do')
51

对于字典

>>> sys.getsizeof({})
240
>>> sys.getsizeof({'a': 1})
240
>>> sys.getsizeof({'a': 1, 'b': 2})
240
>>> sys.getsizeof({'a': 1, 'b': 2, 'c': 3, 'd': 4})
240

我不明白为什么 0 的大小小于其他整数。尽管我可以在向列表或字符串中添加更多元素时找出一种模式,但我不明白 为什么字典的大小是相同的,无论它有多少个键值对.

I don't understand why the size of 0 is less than other integers.

我假设整数对象存储表示整数所需的 int 的数量,然后是那么多 int。所以 0 会比其他数字小,因为它可以用 0 ints 来表示。因此,一旦您遇到不适合单个 int.

的数字,大小将再次增加

I don't understand why the size of the dictionary is the same no matter of the number key-value pairs it has.

对于 dicts 可能是因为散列映射中数组的大小(Python 的 dicts 是)大于元素数。通常它以一些默认大小开始,然后在达到给定阈值时加倍(例如,当它已满 70% 时)。一旦你达到一定数量的元素,你会发现尺寸会增加。

如果您通过重复附加到列表而不是一开始就创建特定大小的列表来创建列表,您将观察到与列表类似的行为。也就是说,如果您从一个空列表开始,然后循环追加到它,同时在每次追加后打印大小,您将看到大小只会增加一些。那是因为底层数组不会在每次追加时调整大小,而是它的大小会在它满时加倍,因此每次调整大小后必须调整它的大小之间的时间会加倍(这给出了附加的分摊 O(1) 时间而不是 O (n)).