问题描述
我想使我的代码更高效(内存).现在,我们有很多函数都采用可迭代的参数,例如:
I want to make my code more (memory-)efficient. Right now we have a lot of functions that take an iterable as parameter like:
def foo(para,meter,iterable):
#...
pass
,有时我们必须为其提供一个空白列表才能正常工作:foo(14,25,[])
.问题是每次构造一个新列表时:它需要在堆上分配,并且列表似乎有64字节的内存(在我自己的机器上,用sys.getsizeof([])
测试),而只有空元组需要(可能是一次)48个字节.
and sometimes we have to provide it an empty list to do its work properly: foo(14,25,[])
. The problem is that each time a new list is constructed: it requires to allocate on the heap, and a list seems to 64 bytes of memory (on my own machine, tested with sys.getsizeof([])
) whereas the empty tuple onlytakes a (potentially one time) 48 bytes.
因此,我想知道空元组是否为常数.由于元组是不可变的,因此可以轻松地将长度为0
(因此()
)的元组在程序中设为常数.这样可以减少构造时间"(没有,因为它只会设置对常量的引用),并减少了分配的内存量.
I was therefore wondering whether the empty tuple is a constant. Since tuples are immutable, one can easily make the tuple with length 0
(so ()
) a constant in the program. This would decrease the "construction time" (well there is none since it only would set a reference to the constant) and reduce the amount of memory allocated.
我的问题是,关于Python解释器(即任何流行的解释器),是否可以保证空元组确实是一个常量,使得()
不需要构造时间或分配额外的内存.
My question is whether there are guarantees regarding the Python interpreter (that is any popular interpreter) that the empty tuple is indeed a constant such that ()
does not require construction time nor allocates additional memory.
用id(..)
进行测试似乎支持这样的理论,即实际上只有一个零元组:
Testing it with id(..)
seems to support the theory that there is indeed only one zero-tuple:
>>> id(())
140290183798856
>>> a = ()
>>> id(a)
140290183798856
但由于某些原因,在运行时Python解释器可能会分叉元组.
but it could be possible that at runtime the Python interpreter forks the tuple for some reason.
推荐答案
在CPython中,空元组是单例.永远只创建一个副本,然后在空生成器上使用()
或tuple()
时可以重复使用.
In CPython, the empty tuple is a singleton. Only one copy is created, ever, then reused whenever you use ()
or use tuple()
on an empty generator.
PyTuple_new()
函数基本上是这样做的:
The PyTuple_new()
function essentially does this:
if (size == 0 && free_list[0]) {
op = free_list[0];
Py_INCREF(op);
// ...
return (PyObject *) op;
}
因此,如果元组大小为0(空)并且free_list[0]
对象存在(现有的空元组单例),则只需使用它.
So if the tuple size is 0 (empty) and free_list[0]
object exists (the existing empty tuple singleton), just use that.
请参见如何在CPython中实现元组? free_list
的更多详细信息; CPython还将重用长度为20的已经创建的tuple
实例.
See How is tuple implemented in CPython? for more details on free_list
; CPython will also re-use already-created tuple
instances up to length 20.
这是实施细节.其他实现(Jython,IronPython,PyPy)不必这样做.
This is an implementation detail. Other implementations (Jython, IronPython, PyPy) do not have to do the same.
这篇关于Python中的空元组是否为“常量"?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!