1.为什么要使用__slots__

Python 使用 dicts(hash table)缓存大量的静态资源(属性)。

我们最近在Image类中,用仅仅一行__slots__代码,改变成使用tuple储存,可以节约大量内存空间。

为啥呢?

和list相比,dict 查找和插入的速度极快,不会随着key的增加而增加;dict需要占用大量的内存,内存浪费多。

而list查找和插入的时间随着元素的增加而增加;占用空间小,浪费的内存很少。

python解释器是Cpython,这两个数据结构应该对应C的哈希表和数组。因为哈希表需要额外内存记录映射关系,而数组只需要通过索引就能计算出下一个节点的位置,所以哈希表占用的内存比数组大,也就是dict比list占用的内存更大。

2.默认情况

默认情况下,Python用一个dict来存储对象实例的属性。这在一般情况下还不错,而且非常灵活,乃至你在运行时可以随意设置新的属性。

但是,对一些在”编译”前就知道该有几个固定属性的小class来说,这个dict就有点浪费内存了。而当你把这个小浪费乘上一百万,那可就大不同了。

在Python中,你可以在class中设置__slots__,它是一个包含这些固定的属性名的list。这样Python就不会再使用dict,而且只分配这些属性的空间。

默认情况下:

改成__slots__后:

class Image(object):
__slots__ = ['id', 'name', 'age'] def __init__(self, id, name, age):
self.id = id
self.name = name
self.age = age i=Image(1,'wqbin',18)
i.__dict__

你还可以用collections.namedtuple,它允许访问参数,但只占用一个tuple的空间。这跟__slots__类似。不过我总觉得继承一个namedtuple类很奇怪。另外,如果你需要自定义初始化,你应该重载__new__而不是__init__。

警告:不要贸然进行这个优化,把它用在所有地方。这种做法不利于代码维护,而且只有当你有数以千计的实例的时候才会有明显效果。

译注:作者在评论中关于”不利于代码维护“的说法:

webreac:我觉得__slots__关键字不只是速度优化(注:这里应该是内存优化),也是类字段名的一个可靠”文档“。这有利于代码维护。为什么你觉得它不好?

Ben Hoyt(作者):有趣的说法——我不确定应不应该把__slots__作为文档。不过的确是不错的注意。我之前这么说的原因是,你需要对字段名”定义“两次(不够DRY)。namedtuple也类似

3.空间节省效果

如何查看内存占用

class Foobar(object):
__slots__=('x')
def __init__(self, x):
self.x = x @profile
def main():
f = [Foobar(42) for i in range(1000000)] if __name__ == "__main__":
main()

class Foobar(object):
def __init__(self, x):
self.x = x @profile
def main():
f = [Foobar(42) for i in range(1000000)] if __name__ == "__main__":
main()

100百万个实例化对象的内存占用从208M降低到93M

最新文章

  1. 项目:学生查看自己的作业情况和分数(php)
  2. 自动插入数据sql
  3. Android 点击文字实现跳转
  4. win7 64位搭建scrapy
  5. 养成一个SQL好习惯带来一笔大财富
  6. 自定义带有图片的PreferenceActivity
  7. aaalogo写入中文出错的解决方法
  8. java之JDBC
  9. IP地址分类及特殊IP地址
  10. C++ 面向对象学习1
  11. leetcode第13题--Roman to Integer
  12. [置顶] NS2中对TCP数据包和ACK包的TCP Sink类的主要实现代码详尽剖析--吐血放送
  13. 软件raid 5
  14. angularjs的几种常见写法
  15. 大数据 --> Spark与Hadoop对比
  16. crm 数据展示 和分页思想(一)
  17. 事务隔离级别之Read Uncommitted/WITH(NOLOCK)
  18. zabbix添加监控Mysql
  19. scikit-learn入门导航
  20. 第二节:Linux下检出项目和提交项目

热门文章

  1. 并发-synchronized
  2. Design Linked List
  3. Python time strptime()方法
  4. LEN()和DATALENGTH()的区别
  5. Magazine Delivery(POJ1695)【DP】
  6. Linux就该这么学——初识vim编辑器
  7. 文件操作:w,w+,r,r+,a,wb,rb
  8. paramiko-ssh实例
  9. C# WPF集中引用图片等资源的路劲方式
  10. 客户端注册Cannot execute request on any known server解决