用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中super关键字用法实例分析
May 28 Python
利用Python操作消息队列RabbitMQ的方法教程
Jul 19 Python
利用Python暴力破解zip文件口令的方法详解
Dec 21 Python
Python数据可视化教程之Matplotlib实现各种图表实例
Jan 13 Python
Python和Go语言的区别总结
Feb 20 Python
python3下载抖音视频的完整代码
Jun 05 Python
python openvc 裁剪、剪切图片 提取图片的行和列
Sep 19 Python
Tensorflow 多线程与多进程数据加载实例
Feb 05 Python
python next()和iter()函数原理解析
Feb 07 Python
Python基于codecs模块实现文件读写案例解析
May 11 Python
python 通过exifread读取照片信息
Dec 24 Python
简单且有用的Python数据分析和机器学习代码
Jul 02 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
laravel如何开启跨域功能示例详解
2017/08/31 PHP
js中判断文本框是否为空的两种方法
2011/07/31 Javascript
JavaScipt中栈的实现方法
2016/02/17 Javascript
深入理解JavaScript中的对象复制(Object Clone)
2016/05/18 Javascript
浅谈javascript基础之客户端事件驱动
2016/06/10 Javascript
浅谈js常用内置方法和对象
2016/09/24 Javascript
省市区三级联动jquery实现代码
2020/04/15 Javascript
Vue.js中数组变动的检测详解
2016/10/12 Javascript
详解AngularJS 模块化
2017/06/14 Javascript
vue-lazyload图片延迟加载插件的实例讲解
2018/02/09 Javascript
利用adb shell和node.js实现抖音自动抢红包功能(推荐)
2018/02/22 Javascript
JavaScript 五大常见函数
2018/03/23 Javascript
js限制输入框只能输入数字(onkeyup触发)
2018/09/28 Javascript
微信小程序自定义组件的实现方法及自定义组件与页面间的数据传递问题
2018/10/09 Javascript
Vue 子组件与数据传递问题及注意事项
2019/07/11 Javascript
thinkjs微信中控之微信鉴权登陆的实现代码
2019/08/08 Javascript
vue中keep-alive、activated的探讨和使用详解
2020/07/26 Javascript
vue 避免变量赋值后双向绑定的操作
2020/11/07 Javascript
Python的Flask框架中Flask-Admin库的简单入门指引
2015/04/07 Python
python 遍历字符串(含汉字)实例详解
2017/04/04 Python
关于python pyqt5安装失败问题的解决方法
2017/08/08 Python
Django 实现外键去除自动添加的后缀‘_id’
2019/11/15 Python
python 遗传算法求函数极值的实现代码
2020/02/11 Python
如何理解Python中的变量
2020/06/01 Python
美国乡村商店:Plow & Hearth
2016/09/12 全球购物
中间件的定义
2016/08/09 面试题
环境工程专业个人求职信
2013/12/05 职场文书
《诺贝尔》教学反思
2014/02/17 职场文书
环境科学专业求职信
2014/08/04 职场文书
无犯罪记录证明范本
2014/09/15 职场文书
门店店长岗位职责
2015/04/14 职场文书
结婚幸福感言
2015/08/01 职场文书
自书遗嘱范文
2015/08/07 职场文书
Vue图片裁剪组件实例代码
2021/07/02 Vue.js
Python selenium绕过webdriver监测执行javascript
2022/04/12 Python
Docker官方工具docker-registry案例演示
2022/04/13 Servers