用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命名空间详解
Aug 18 Python
python中lambda函数 list comprehension 和 zip函数使用指南
Sep 28 Python
python实现自动重启本程序的方法
Jul 09 Python
浅谈Python的异常处理
Jun 19 Python
Python判断中文字符串是否相等的实例
Jul 06 Python
Python+OpenCV图片局部区域像素值处理详解
Jan 23 Python
python实现动态创建类的方法分析
Jun 25 Python
Python实现基于socket的udp传输与接收功能详解
Nov 15 Python
Python实现括号匹配方法详解
Feb 10 Python
jupyter notebook 多环境conda kernel配置方式
Apr 10 Python
Python字符串格式化常用手段及注意事项
Jun 17 Python
Python操作Excel的学习笔记
Feb 18 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
解析数组非数字键名引号的必要性
2013/08/09 PHP
php下载excel无法打开的解决方法
2013/12/24 PHP
PHP使用递归算法无限遍历数组示例
2017/01/13 PHP
php实现JWT验证的实例教程
2020/11/26 PHP
javascript 读取图片文件的大小
2009/06/25 Javascript
MooTools 页面滚动浮动层智能定位实现代码
2011/08/23 Javascript
商城常用滚动的焦点图效果代码简单实用
2013/03/28 Javascript
5秒后跳转到另一个页面的js代码
2013/10/12 Javascript
NodeJS学习笔记之网络编程
2014/08/03 NodeJs
JavaScript的null和undefined区别示例介绍
2014/09/15 Javascript
根据配置文件加载js依赖模块
2014/12/29 Javascript
jquery插件pagination实现无刷新ajax分页
2015/09/30 Javascript
基于javascript制作微信聊天面板
2020/08/09 Javascript
Bootstrap栅格系统使用方法及页面调整变形的解决方法
2017/03/10 Javascript
JS实现列表页面隔行变色效果
2017/03/25 Javascript
axios全局注册,设置token,以及全局设置url请求网段的方法
2018/09/25 Javascript
Vue 页面权限控制和登陆验证功能的实例代码
2019/06/20 Javascript
解决layui table表单提示数据接口请求异常的问题
2019/09/24 Javascript
Node.js API详解之 readline模块用法详解
2020/05/22 Javascript
用Python进行行为驱动开发的入门教程
2015/04/23 Python
python读写ini配置文件方法实例分析
2015/06/30 Python
python去除空格和换行符的实现方法(推荐)
2017/01/04 Python
python多线程与多进程及其区别详解
2019/08/08 Python
python命令 -u参数用法解析
2019/10/24 Python
HTML5 video标签(播放器)学习笔记(二):播放控制
2015/04/24 HTML / CSS
印尼美容产品购物网站:PerfectBeauty.id
2017/12/01 全球购物
英国玛莎百货新西兰:Marks & Spencer New Zealand
2019/07/21 全球购物
德国户外装备、登山运动和攀岩商店:tapir store
2020/02/12 全球购物
什么是.net的Remoting技术
2016/07/08 面试题
某/etc/fstab文件中的某行如下: /dev/had5 /mnt/dosdata msdos defaults,usrquota 1 2 请解释其含义
2013/09/18 面试题
2014年3.15团委活动总结
2014/03/16 职场文书
现场活动策划方案
2014/08/22 职场文书
优秀教师推荐材料
2014/12/16 职场文书
单位工资证明范本
2015/06/12 职场文书
python 下载文件的几种方式分享
2021/04/07 Python
Redis 持久化 RDB 与 AOF的执行过程
2021/11/07 Redis