用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的多态性实例分析
Jul 07 Python
Python作用域用法实例详解
Mar 15 Python
python 生成器协程运算实例
Sep 04 Python
python matlibplot绘制多条曲线图
Feb 19 Python
Python eval的常见错误封装及利用原理详解
Mar 26 Python
python爬虫实现中英翻译词典
Jun 25 Python
PyTorch中Tensor的维度变换实现
Aug 18 Python
Python一行代码解决矩阵旋转的问题
Nov 30 Python
Pycharm最新激活码2019(推荐)
Dec 31 Python
Pycharm如何导入python文件及解决报错问题
May 10 Python
关于python中readlines函数的参数hint的相关知识总结
Jun 24 Python
Python函数对象与闭包函数
Apr 13 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/09/30 PHP
浅谈php数组array_change_key_case() 函数和array_chunk()函数
2016/10/22 PHP
jQuery效果 slideToggle() 方法(在隐藏和显示之间切换)
2011/06/28 Javascript
Javascript处理DOM元素事件实现代码
2012/05/23 Javascript
js实现简洁的滑动门菜单(选项卡)效果代码
2015/09/04 Javascript
jQuery无刷新分页完整实例代码
2015/10/27 Javascript
React.js入门学习第一篇
2016/03/30 Javascript
JavaScript数据结构链表知识详解
2016/11/21 Javascript
jQuery向webApi提交post json数据
2017/01/16 Javascript
jQuery插件zTree实现更新根节点中第i个节点名称的方法示例
2017/03/08 Javascript
mui框架 页面无法滚动的解决方法(推荐)
2018/01/25 Javascript
js闭包学习心得总结
2018/04/17 Javascript
vue.js前后端数据交互之提交数据操作详解
2018/04/24 Javascript
jQuery 实现批量提交表格多行数据的方法
2018/08/09 jQuery
利用hasOwnProperty给数组去重的面试题分享
2018/11/05 Javascript
深入理解Vue keep-alive及实践总结
2019/08/21 Javascript
vue 解决数组赋值无法渲染在页面的问题
2019/10/28 Javascript
[57:18]DOTA2上海特级锦标赛主赛事日 - 1 败者组第一轮#3VP VS VG
2016/03/03 DOTA
在Apache服务器上同时运行多个Django程序的方法
2015/07/22 Python
Python使用Srapy框架爬虫模拟登陆并抓取知乎内容
2016/07/02 Python
win10系统中安装scrapy-1.1
2016/07/03 Python
python爬虫之模拟登陆csdn的实例代码
2018/05/18 Python
python 利用已有Ner模型进行数据清洗合并代码
2019/12/24 Python
Matplotlib 折线图plot()所有用法详解
2020/07/28 Python
HTML5+lufylegend实现游戏中的卷轴
2016/02/29 HTML / CSS
宝拉珍选澳大利亚官方购物网站:Paula’s Choice澳大利亚
2016/09/13 全球购物
方太官方网上商城:销售方太抽油烟机、燃气灶、消毒柜等
2017/01/17 全球购物
车间主管岗位职责
2013/11/14 职场文书
小学美术教学反思
2014/02/01 职场文书
2014年公司植树节活动方案
2014/03/04 职场文书
2014年人力资源部工作总结
2014/11/19 职场文书
幼儿园毕业典礼园长致辞
2015/07/29 职场文书
医护人员继续教育学习心得体会
2016/01/19 职场文书
HTML5中 rem适配方案与 viewport 适配问题详解
2021/04/27 HTML / CSS
python中__slots__节约内存的具体做法
2021/07/04 Python
python读取并查看npz/npy文件数据以及数据显示方法
2022/04/14 Python