Python结构的内存占用大小
有没有关于Python数据结构在32位和64位平台上内存大小的参考资料?
如果没有的话,这个信息在Stack Overflow上会很有用。越详细越好!那么以下这些Python结构大概占用多少字节呢(根据len
和内容类型的不同)?
int
(整数)float
(浮点数)- 引用
str
(字符串)- unicode字符串
tuple
(元组)list
(列表)dict
(字典)set
(集合)array.array
(数组)numpy.array
(NumPy数组)deque
(双端队列)- 新式类对象
- 旧式类对象
- ... 还有我忘记的其他所有东西!
(对于那些只保存其他对象引用的容器,我们显然不想计算它们所包含项的大小,因为这些项可能是共享的。)
此外,有没有办法在运行时获取一个对象所占用的内存(可以是递归的,也可以不是)?
7 个回答
我一直很高兴地使用pympler来完成这类任务。它支持很多版本的Python,特别是里面的asizeof
模块,甚至可以追溯到2.2版本!
比如,使用hughdbrown的例子,只需在开头加上from pympler import asizeof
,在最后加上print asizeof.asizeof(v)
,我在MacOSX 10.5上使用系统自带的Python 2.5时看到的结果是:
$ python pymp.py
set 120
unicode 32
tuple 32
int 16
decimal 152
float 16
list 40
object 0
dict 144
str 32
显然这里有一些近似值,但我发现它在分析程序占用空间和优化方面非常有用。
这些回答都只是收集了一些表面的大小信息。我猜这里来的人可能想知道“这个复杂的对象在内存中占多大?”
这里有一个很好的答案: https://goshippo.com/blog/measure-real-size-any-python-object/
重点是:
import sys
def get_size(obj, seen=None):
"""Recursively finds size of objects"""
size = sys.getsizeof(obj)
if seen is None:
seen = set()
obj_id = id(obj)
if obj_id in seen:
return 0
# Important mark as seen *before* entering recursion to gracefully handle
# self-referential objects
seen.add(obj_id)
if isinstance(obj, dict):
size += sum([get_size(v, seen) for v in obj.values()])
size += sum([get_size(k, seen) for k in obj.keys()])
elif hasattr(obj, '__dict__'):
size += get_size(obj.__dict__, seen)
elif hasattr(obj, '__iter__') and not isinstance(obj, (str, bytes, bytearray)):
size += sum([get_size(i, seen) for i in obj])
return size
用法如下:
In [1]: get_size(1)
Out[1]: 24
In [2]: get_size([1])
Out[2]: 104
In [3]: get_size([[1]])
Out[3]: 184
如果你想更深入了解Python的内存模型,这里有一篇很棒的文章,里面有类似的“总大小”代码片段,作为更长解释的一部分: https://code.tutsplus.com/tutorials/understand-how-much-memory-your-python-objects-use--cms-25609
之前有个问题提到,想要知道一个对象的大小,可以使用 sys.getsizeof() 这个方法,引用如下:
>>> import sys
>>> x = 2
>>> sys.getsizeof(x)
14
>>> sys.getsizeof(sys.getsizeof)
32
>>> sys.getsizeof('this')
38
>>> sys.getsizeof('this also')
48
你可以这样做:
>>> import sys
>>> import decimal
>>>
>>> d = {
... "int": 0,
... "float": 0.0,
... "dict": dict(),
... "set": set(),
... "tuple": tuple(),
... "list": list(),
... "str": "a",
... "unicode": u"a",
... "decimal": decimal.Decimal(0),
... "object": object(),
... }
>>> for k, v in sorted(d.iteritems()):
... print k, sys.getsizeof(v)
...
decimal 40
dict 140
float 16
int 12
list 36
object 8
set 116
str 25
tuple 28
unicode 28
2012年9月30日
python 2.7(在linux上,32位):
decimal 36
dict 136
float 16
int 12
list 32
object 8
set 112
str 22
tuple 24
unicode 32
python 3.3(在linux上,32位):
decimal 52
dict 144
float 16
int 14
list 32
object 8
set 112
str 26
tuple 24
unicode 26
2016年8月1日
在OSX上,Python 2.7.10(默认版本,2015年10月23日,19:19:21)[GCC 4.2.1 兼容 Apple LLVM 7.0.0 (clang-700.0.59.5) ] 在darwin系统上运行
decimal 80
dict 280
float 24
int 24
list 72
object 16
set 232
str 38
tuple 56
unicode 52