【发布时间】:2012-12-02 16:01:32
【问题描述】:
在 Python 解释器中查询:
Python 2.7.3 (default, Apr 10 2012, 23:31:26) [MSC v.1500 32 bit (Intel)] on win
32
Type "help", "copyright", "credits" or "license" for more information.
>>> k = [i for i in xrange(9999999)]
>>> import sys
>>> sys.getsizeof(k)/1024/1024
38
>>>
在这里 - 看看它需要多少 RAM:
语句del k后的内存使用:
在gc.collect()之后:
为什么预期大小为 38Mb 的整数列表占用 160Mb?
UPD: 这部分问题得到了回答(几乎是立即和多次:))
好的 - 这是另一个谜:
Python 2.7.3 (default, Apr 10 2012, 23:31:26) [MSC v.1500 32 bit (Intel)] on win
32
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> str = 'abcdefg'
>>> sys.getsizeof(str)
28
>>> k = []
>>> for i in xrange(9999999):
... k.append(str)
...
>>> sys.getsizeof(str)*9999999/1024/1024
267
你认为它现在会消耗多少?
(来源:i.imm.io)
str 的大小为 28,而在过去的示例中为 12。因此,预期的内存使用量为 267Mb - 甚至比整数还要多。但它只需要 ~40Mb!
【问题讨论】:
-
附带说明,如果您正在处理大型数值数组,并且内存(我猜是性能?)是一个问题,那么可能值得考虑使用 NumPy。
-
好问题。我认为
getsizeof()只计算列表中指针的大小,但实际的整数值在 C 中存储为PyIntObject结构,每个结构都像任何其他 Python 对象一样有一堆开销。我希望对 Python 内部有更多了解的人(或者现在有更多时间研究它们)可以发布更精确的具体回复作为答案。 :) -
您的第二个示例完全无效。您将一个对同一字符串的引用多次存储到数组中。字符串本身只占用一次空间 - 它始终是同一个对象。
标签: python performance optimization memory-leaks