大型python列表的内存要求

时间:2009-12-31 16:15:12

标签: python memory-management 32bit-64bit

我做了一件愚蠢的事情,比如

from itertools import *
rows = combinations(range(0, 1140), 17)
all_rows = []
for row in rows:
    all_rows.append(row)

毫不奇怪我耗尽内存地址空间(32位python 3.1) 我的问题是,我如何计算一个大型列表需要多少内存地址空间?在这种情况下,列表大约为2.3X10 ^ 37。 我假设python中有一个函数返回我正在寻找的信息,或者实际上是一个较小但相似的列表的大小。那些工具是什么?

4 个答案:

答案 0 :(得分:11)

有一个方便的函数sys.getsizeof()(自Python 2.6起)可以帮助解决这个问题:

>>> import sys
>>> sys.getsizeof(1)  # integer
12
>>> sys.getsizeof([]) # empty list
36
>>> sys.getsizeof(()) # empty tuple
28
>>> sys.getsizeof((1,))  # tuple with one element
32

从中您可以看到每个整数占用12个字节,列表或元组中每个引用的内存为4个字节(在32位机器上)加上开销(分别为36或28个字节)。

如果你的结果的长度为17的整数元组,则每个元组你有17*(12+4)+28或300字节。结果本身是一个列表,所以36个字节加上每个引用4个。找出列表的长度(称之为N),并且36+N*(4+300)为所需的总字节数。

编辑:还有一件事可能会对此结果产生重大影响。 Python根据大多数整数值的需要创建新的整数对象,但对于小的整数对象(根据经验确定为Windows上的Python 2.6.4的范围[-5,256]),它会预先创建它们并重新使用它们。如果您的大部分值小于257,这将显着减少内存消耗。 (在Python上257 is not 257+0; - ))。

答案 1 :(得分:4)

首先而不是写作:

all_rows = []
for row in rows:
    all_rows.append(row)

您可以简单地写一下:

all_rows = list(rows)

这会更有效率。

然后,列表的内存消耗需要考虑两件事:

  • 包含列表的对象的内存消耗;这显然取决于这些对象,它们的类型,以及是否有很多共享
  • 列表本身的内存消耗;列表中的每个对象都由一个指针引用,该指针在32位模式下占用4个字节,在64位模式下占用8个字节;所以,粗略地说,列表本身的大小是列表中对象数量的(4或8个字节)倍(这忽略了固定列表头开销和Python列出的适当数量的过度分配)

顺便说一句,在最近的Python版本中,您可以使用sys.getsizeof()来获取对象的大小:

>>> import sys
>>> sys.getsizeof([None] * 100)
872

答案 2 :(得分:3)

附录:由于您正在处理整数列表并担心内存使用问题,因此还有array - 模块:

  

[array]定义了一个对象类型,它可以紧凑地表示一个基本值数组:字符,整数,浮点数。数组是序列类型,其行为与列表非常相似,只是存储在其中的对象类型受到约束。该类型在对象创建时指定[...]。

答案 3 :(得分:1)

你要求

http://en.wikipedia.org/wiki/Binomial_coefficient

http://www.brpreiss.com/books/opus7/programs/pgm14_10.txt

无论如何,听起来你正试图通过蛮力解决NP完全问题;)