gpt4 book ai didi

Python - 元组和内存管理

转载 作者:行者123 更新时间:2023-11-28 22:41:22 25 4
gpt4 key购买 nike

在回答一个与 Python 相关的问题时,我做了一些实验并发现了一个我无法弄清楚的与元组相关的事情:我很难理解为什么一个空元组比一个包含单个元素的元组占用更多空间(根据 sys.getsizeof())。下面的代码是在 64 位 Debian Jessie 系统上使用 Python 2.7.9 的上游版本执行的(也使用 Python 3.4.2 进行了测试,其中值略有不同,但我所说的整体行为仍然存在):

>> sys.getsizeof(())
56
>> sys.getsizeof((1))
24
>> sys.getsizeof((1,2))
72

如您所见,空元组与单项元组之间存在很大差异(更准确地说是 2.3 倍)。知道这里发生了什么吗?由于元组是递归数据结构,我假设 sys.getsizeof() 返回的值是元组对象本身占用的内存量加上对它包含的对象的引用(如果元组将元素存储为引用而不是值——我不知道)。我最初的想法是,像字典一样,元组是在内存中创建的,具有一定的默认大小,可以容纳几个元素。我忘记了空字典保留内存的元素的确切数量,但这是我用一个小例子的意思:

>> sys.getsizeof({})
280
>> sys.getsizeof({"a":0})
280
>> sys.getsizeof({"a":0, "b":1})
280

然而,查看元组似乎并没有表现出相同的行为,因为元组在第一个元素添加到较小尺寸后收缩,然后随着每个元素添加到它而增长(如预期)。除此之外,列表似乎没有出现相同的行为:

>> sys.getsizeof([])
72
>> sys.getsizeof([1])
80
>> sys.getsizeof([1,2])
88

空列表在内存方面比具有 1 个或多个元素的列表小 - 完全正常。

我的第二个想法是,单元素元组以某种方式转换为它包含的单个对象,所有这些都以某种方式包装,因此它看起来实际上是一个列表(这就是为什么 len()作品)。示例:

>> sys.getsizeof((1))
24
>> sys.getsizeof(1)
24

这似乎是可能的,但我不相信它真的发生了。

最佳答案

您不是在创建单项元组。任何表达式都可以包含在括号中而不改变其含义,因此 (1)1 相同。要创建单个元素元组,请编写 (1,)。当你这样做时,内存消耗应该变得更合理。

But how can an integer require 24 bytes? Aren't integers usually 8 bytes at most?

在 Python 3 中,所有整数都是任意精度的,即使在 Python 2 中,包括整数在内的所有对象在引用计数、类型信息和其他元数据方面都有一定的开销。 24 个字节对于一个成熟的 Python 对象来说实际上是相当合理的。

(从技术上讲,小整数是驻留的,因此在这种特殊情况下可以说引用计数是不必要的,但删除它会使解释器的其他部分复杂化,而没有任何显着好处。)

在我回答的同时,我还想澄清一些事情:

(if tuples store elements as references and not as values - that I don't know)

一般来说,Python 不允许 Python 对象实际包含彼此。在C源代码中,你会看到很多PyObject*变量,但是没有PyObject变量。 Python 对象存在于堆中,彼此完全独立。换句话说,是的,元组存储的是引用,而不是实际的对象。

My initial thought was that like dictionaries tuples are created in memory with a certain default size that can hold a couple of elements.

没有理由这样做。元组有固定的大小。正式地,它们是不可变的,并且在创建后不会改变。非正式地,它们可以在 C 级别进行更改,但这些更改不应该对 Python 代码可见;您在创建元组之后但在将其用于任何事情之前修改一次,此后您不会再次修改它。此外,这些更改实际上并没有改变大小,它们只是填充已经存在的数组槽。

由于这种不变性,元组没有理由存储比实际更多的元素。它们不需要支持快速附加或其他大小更改操作。

关于Python - 元组和内存管理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32674679/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com