Python减少字典对象内存大小的方法

描述

程序执行过程中,如果RAM中有大量的对象在运行,就可能会出现内存问题,特别是在对可用内存总量有限的情况下。

下面是一些减少字典对象内存大小的方法,这些方法可以显著减少对象所需的RAM大小。

字典

在Python里用字典来表示结构信息是非常方便的:

  1. >>> ob ={'x':1,'y':2,'z':3}

  2. >>> x = ob['x']

  3. >>> ob['y']= y

但我们来看看它的内存消耗:

  1. >>>print(sys.getsizeof(ob))

  2. 240

这个数额看起来好像挺小,但是当你想要创造许多这样的变量时就积少成多了:

对象数目内存大小
1 000 000240 Mb
10 000 0002.40 Gb
100 000 00024 Gb

解决方案

用类实例来代替字典:

  1. classPoint:

  2. def __init__(self, x, y, z):

  3. self.x = x

  4. self.y = y

  5. self.z = z

  6. >>> ob =Point(1,2,3)

  7. >>> x = ob.x

  8. >>> ob.y = y

类实例各个部分的内存大小:

FieldSize (bytes)
PyGC_Head24
PyObject_HEAD16
weakref8
dict8
TOTAL:56

如果你不是很了解类和实例,可以看廖雪峰的这篇文章:
https://www.liaoxuefeng.com/wiki/1016959663602400/1017496031185408

这里的__weakref__是对这个对象的弱引用列表的引用,而__dict__是对类实例字典的引用,它包含实例属性的值。从Python 3.3开始, 类的所有实例用共享空间存储字典的keys. 这减少了内存中实例的大小:

  1. >>>print(sys.getsizeof(ob), sys.getsizeof(ob.__dict__))

  2. 56 112

56+112=168 < 240. 因此,大量的类实例占用的内存比普通字典(dict)要少:

实例数目大小
1 000 000168 Mb
10 000 0001.68 Gb
100 000 00016.8 Gb

字典占实例大小的百分比为112/168=67%, 我们还是可以看出,实例中字典的大小严重影响了RAM中实例的大小。下面有更好的方法。

带__slots__的类实例

通过消除__dict__和weakref__,可以显著减少RAM中的类实例的大小。用__slots__是有可能做到的:

  1. classPoint:

  2. __slots__ ='x','y','z'

  3. def __init__(self, x, y, z):

  4. self.x = x

  5. self.y = y

  6. self.z = z

  7. >>> ob =Point(1,2,3)

  8. >>>print(sys.getsizeof(ob))

  9. 64

RAM中的对象明显变小:

FieldSize (bytes)
PyGC_Head24
PyObject_HEAD16
x8
y8
z8
TOTAL:64

今日重点:在类定义中使用__slots__会显著减少大量实例的内存占用

实例数目大小
1 000 00064 Mb
10 000 000640 Mb
100 000 0006.4 Gb

目前,这是大幅度减少RAM中类实例的内存占用的主要方法。相比于单纯用字典,减少了(240-64)/240= 73% 的内存占用。

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分