用Python中的__slots__缓存资源以节省内存开销的方法


Posted in Python onApril 02, 2015

我们曾经提到,Oyster.com的Python web服务器怎样利用一个巨大的Python dicts(hash table),缓存大量的静态资源。我们最近在Image类中,用仅仅一行__slots__代码,让每个6G内存占用的服务进程(共4个),省出超过2G来。

这是其中一个服务器在部署代码前后的截图:

用Python中的__slots__缓存资源以节省内存开销的方法

我们alloc了大约一百万个类似如下class的实例:
 
class Image(object):
    def __init__(self, id, caption, url):
        self.id = id
        self.caption = caption
        self.url = url
        self._setup()
 
    # ... other methods ...

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

但是,对一些在”编译”前就知道该有几个固定属性的小class来说,这个dict就有点浪费内存了。而当你把这个小浪费乘上一百万,那可就大不同了。在Python中,你可以在class中设置__slots__,它是一个包含这些固定的属性名的list。这样Python就不会再使用dict,而且只分配这些属性的空间。
 
class Image(object):
    __slots__ = ['id', 'caption', 'url']
 
    def __init__(self, id, caption, url):
        self.id = id
        self.caption = caption
        self.url = url
        self._setup()
 
    # ... other methods ...

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

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

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

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

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

Python 相关文章推荐
Python中优化NumPy包使用性能的教程
Apr 23 Python
Python对文件操作知识汇总
May 15 Python
Python快速从注释生成文档的方法
Dec 26 Python
python爬虫之百度API调用方法
Jun 11 Python
django+xadmin+djcelery实现后台管理定时任务
Aug 14 Python
python实现决策树分类(2)
Aug 30 Python
Python根据欧拉角求旋转矩阵的实例
Jan 28 Python
用python拟合等角螺线的实现示例
Dec 27 Python
python实现FTP循环上传文件
Mar 20 Python
Django的ListView超详细用法(含分页paginate)
May 21 Python
python实现简单的井字棋游戏(gui界面)
Jan 22 Python
Python图像处理库PIL详细使用说明
Apr 06 Python
用Python的线程来解决生产者消费问题的示例
Apr 02 #Python
用实例分析Python中method的参数传递过程
Apr 02 #Python
使用优化器来提升Python程序的执行效率的教程
Apr 02 #Python
使用Python脚本对Linux服务器进行监控的教程
Apr 02 #Python
在Python编程过程中用单元测试法调试代码的介绍
Apr 02 #Python
用Python的Django框架完成视频处理任务的教程
Apr 02 #Python
用map函数来完成Python并行任务的简单示例
Apr 02 #Python
You might like
PHP设计模式之代理模式的深入解析
2013/06/13 PHP
php使用GeoIP库实例
2014/06/27 PHP
php防止伪造的数据从URL提交方法
2014/06/27 PHP
PHP解压tar.gz格式文件的方法
2016/02/14 PHP
JavaScript 中的日期和时间及表示标准介绍
2013/08/21 Javascript
jQuery的one()方法用法实例
2015/01/19 Javascript
深入学习JavaScript中的原型prototype
2015/08/13 Javascript
AngularJS转换响应内容
2016/01/27 Javascript
分享jQuery网页元素拖拽插件
2020/12/01 Javascript
jQuery Ajax 加载数据时异步显示加载动画
2016/08/01 Javascript
轻松实现jquery选项卡切换效果
2016/10/10 Javascript
在JS中如何把毫秒转换成规定的日期时间格式实例
2017/05/11 Javascript
深入理解ES6的迭代器与生成器
2017/08/19 Javascript
JS实现不用中间变量temp 实现两个变量值得交换方法
2018/02/04 Javascript
Vue数据双向绑定原理及简单实现方法
2018/05/18 Javascript
解决vue点击控制单个样式的问题
2018/09/05 Javascript
vuejs简单验证码功能完整示例
2019/01/08 Javascript
vue路由守卫及路由守卫无限循环问题详析
2019/09/05 Javascript
js实现烟花特效
2020/03/02 Javascript
举例讲解Python编程中对线程锁的使用
2016/07/12 Python
Python实现图片滑动式验证识别方法
2017/11/09 Python
基于python内置函数与匿名函数详解
2018/01/09 Python
numpy linalg模块的具体使用方法
2019/05/26 Python
python实现一次性封装多条sql语句(begin end)
2020/06/06 Python
解决Pymongo insert时会自动添加_id的问题
2020/12/05 Python
英国、欧洲和全球租车服务:Avis英国
2016/08/29 全球购物
2014年端午节演讲稿范文
2014/05/23 职场文书
羽毛球社团活动总结
2014/06/27 职场文书
2015年教师学期工作总结
2015/04/30 职场文书
学生检讨书怎么写
2015/05/07 职场文书
预备党员介绍人意见
2015/06/01 职场文书
工作简报怎么写
2015/07/21 职场文书
护士医德医风心得体会
2016/01/25 职场文书
nginx处理http请求实现过程解析
2021/03/31 Servers
jquery插件实现搜索历史
2021/04/24 jQuery
十个Python自动化常用操作,即拿即用
2021/05/10 Python