用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实现的防DDoS脚本
Feb 08 Python
对Python新手编程过程中如何规避一些常见问题的建议
Apr 01 Python
Python的Django框架中TEMPLATES项的设置教程
May 29 Python
用Python实现斐波那契(Fibonacci)函数
Mar 25 Python
Python自动化运维和部署项目工具Fabric使用实例
Sep 18 Python
Python温度转换实例分析
Jan 17 Python
Python中pillow知识点学习
Apr 30 Python
用TensorFlow实现lasso回归和岭回归算法的示例
May 02 Python
Python入门Anaconda和Pycharm的安装和配置详解
Jul 16 Python
python 实现rolling和apply函数的向下取值操作
Jun 08 Python
解决Keyerror ''acc'' KeyError: ''val_acc''问题
Jun 18 Python
python自动统计zabbix系统监控覆盖率的示例代码
Apr 03 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/05 PHP
探讨如何在php168_cms中提取验证码
2013/06/08 PHP
Yii2组件之多图上传插件FileInput的详细使用教程
2016/06/20 PHP
Laravel事件监听器用法实例分析
2019/03/12 PHP
Javascript的IE和Firefox兼容性汇编
2006/07/01 Javascript
JS 建立对象的方法
2007/04/21 Javascript
表单填写时用回车代替TAB的实现方法
2007/10/09 Javascript
原生js做的手风琴效果的导航菜单
2013/11/08 Javascript
js实现div闪烁原理及实现代码
2014/06/24 Javascript
纯js模拟div层弹性运动的方法
2015/07/27 Javascript
JS实现网页Div层Clone拖拽效果
2015/09/26 Javascript
深入浅出 jQuery中的事件机制
2016/08/23 Javascript
纯JS代码实现隔行变色鼠标移入高亮
2016/11/23 Javascript
node.js实现复制文本到剪切板的功能
2017/01/23 Javascript
基于vue的fullpage.js单页滚动插件
2017/03/20 Javascript
20行js代码实现的贪吃蛇小游戏
2017/06/20 Javascript
利用JS制作万年历的方法
2017/08/16 Javascript
js原生日历的实例(推荐)
2017/10/31 Javascript
用Webpack构建Vue项目的实践
2017/11/07 Javascript
Nodejs实现的操作MongoDB数据库功能完整示例
2019/02/02 NodeJs
JS中this的4种绑定规则详解
2020/02/04 Javascript
详解React 条件渲染
2020/07/08 Javascript
[02:19]DOTA选手解说齐贺岁
2018/02/11 DOTA
[46:23]完美世界DOTA2联赛PWL S2 FTD vs Magma 第一场 11.20
2020/11/23 DOTA
Python实现基于权重的随机数2种方法
2015/04/28 Python
Python+微信接口实现运维报警
2016/08/27 Python
python和mysql交互操作实例详解【基于pymysql库】
2019/06/04 Python
详解pandas中MultiIndex和对象实际索引不一致问题
2019/07/23 Python
python 实现让字典的value 成为列表
2019/12/16 Python
python实现滑雪者小游戏
2020/02/22 Python
综合实践活动总结
2014/05/05 职场文书
医院领导班子四风对照检查材料
2014/09/27 职场文书
2014年企业员工工作总结
2014/12/09 职场文书
教师病假条范文
2015/08/17 职场文书
公司年会主持词范文!
2019/05/07 职场文书
SQL实战演练之网上商城数据库商品类别数据操作
2021/10/24 MySQL