例如,存储一百万(32位)整数列表需要多少内存?
alist = range(1000000) # or list(range(1000000)) in Python 3.0
Dan Lenski.. 23
"这取决于." Python为列表分配空间,以便实现将元素附加到列表的分摊的常量时间.
在实践中,这对于当前实现意味着......列表总是具有为两个幂的元素分配的空间.所以range(1000000)实际上会分配一个足够大的列表来容纳2 ^ 20个元素(~1045万).
这只是存储列表结构本身所需的空间(这是指向每个元素的Python对象的指针数组).32位系统每个元素需要4个字节,64位系统每个元素需要8个字节.
此外,您需要空间来存储实际元素.这种差异很大.对于小整数(当前为-5到256),不需要额外的空间,但是对于较大的数字,Python为每个整数分配一个新对象,这需要10-100个字节并且往往会破坏内存.
底线:它很复杂,Python列表不是存储大型同构数据结构的好方法.为此,使用array
模块,或者,如果您需要进行矢量化数学,请使用NumPy.
PS-Tuples与列表不同,并不是为了逐步附加元素而设计的.我不知道分配器是如何工作的,但是甚至不考虑将它用于大型数据结构:-)
"这取决于." Python为列表分配空间,以便实现将元素附加到列表的分摊的常量时间.
在实践中,这对于当前实现意味着......列表总是具有为两个幂的元素分配的空间.所以range(1000000)实际上会分配一个足够大的列表来容纳2 ^ 20个元素(~1045万).
这只是存储列表结构本身所需的空间(这是指向每个元素的Python对象的指针数组).32位系统每个元素需要4个字节,64位系统每个元素需要8个字节.
此外,您需要空间来存储实际元素.这种差异很大.对于小整数(当前为-5到256),不需要额外的空间,但是对于较大的数字,Python为每个整数分配一个新对象,这需要10-100个字节并且往往会破坏内存.
底线:它很复杂,Python列表不是存储大型同构数据结构的好方法.为此,使用array
模块,或者,如果您需要进行矢量化数学,请使用NumPy.
PS-Tuples与列表不同,并不是为了逐步附加元素而设计的.我不知道分配器是如何工作的,但是甚至不考虑将它用于大型数据结构:-)
有用的链接:
如何获取python对象的内存大小/用法
python对象的内存大小?
如果将数据放入字典,我们如何计算数据大小?
但他们没有给出明确的答案.要走的路:
测量Python解释器使用/不使用列表所消耗的内存(使用OS工具).
使用第三方扩展模块定义某种sizeof(PyObject).
更新:
食谱546530:Python对象的大小(修订)
import asizeof N = 1000000 print asizeof.asizeof(range(N)) / N # -> 20 (python 2.5, WinXP, 32-bit Linux) # -> 33 (64-bit Linux)
解决问题的"元组"部分
在典型的构建配置中声明CPython的PyTuple归结为:
struct PyTuple { size_t refcount; // tuple's reference count typeobject *type; // tuple type object size_t n_items; // number of items in tuple PyObject *items[1]; // contains space for n_items elements };
PyTuple实例的大小在构造过程中是固定的,之后无法更改.PyTuple占用的字节数可以计算为
sizeof(size_t) x 2 + sizeof(void*) x (n_items + 1)
.
这给出了元组的浅层大小.要获得完整大小,还需要添加以PyTuple::items[]
数组为根的对象图消耗的总字节数.
值得注意的是,元组构造例程确保只创建单个空元组实例(单例).
参考文献: Python.h, object.h, tupleobject.h, tupleobject.c