用Python中的__slots__缓存资源以节省内存开销的方法
作者:Ben Hoyt 发布时间:2021-06-21 10:33:40
我们曾经提到,Oyster.com的Python web服务器怎样利用一个巨大的Python dicts(hash table),缓存大量的静态资源。我们最近在Image类中,用仅仅一行__slots__代码,让每个6G内存占用的服务进程(共4个),省出超过2G来。
这是其中一个服务器在部署代码前后的截图:
我们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实现pdf文档转txt的方法。分享给大家供大家参考,具体如下:首先,这是一个比较粗糙的版本,因为已经够用了,而且对
- 前言今天学习Django框架,用ajax向后台发送post请求,直接报了403错误,说CSRF验证失败;先前用模板的话都是在里面加一个 {%
- Python中可以使用collections中的defaultdict类实现创建进行统一初始化的字典。这里总结两种常用一点的初始化方式,分别
- 工具:Pycharm,Django1.11.9.1.下载django_admin_bootstrappedpip install djang
- 天气查询python小程序第0步:导入工具库第一步:生成查询天气的url链接第二步:访问url链接,解析服务器返回的json数据,变成pyt
- 工作中我们经常要两段代码的区别,或者需要查看接口返回的字段与预期是否一致,如何快速定位出两者的差异?除了一些对比的工具比如Beyond Co
- 在目标检测的模型训练中, 我们通常都会有一个特征提取网络backbone, 例如YOLO使用的darknet SSD使用的VGG-16。为了
- 本次分析一下Logger.info的流程1. Logger.info源码: def info(self, msg, *args, **kwa
- 问题描述现有一个有向无权图。如下图所示: 问题:使用某个顶点s作为输入参数,找出从s到所有其他顶点的最短路径。 说明:因为是无权
- 1.1 什么是Mysql多实例?简单的说,Mysql多实例就是在一台服务器上同时开启多个不同的服务端口(如 : 3306/3307/3308
- 写在前面因为暂时还没有想好做什么具体的某个项目来提升对python的理解,所以就自己想着做一下小玩意来加强一下自己对一些库和方法的理解分析1
- golang常用库:gorilla/mux-http路由库使用golang常用库:配置文件解析库-viper使用golang常用库:操作数据
- 自定义比较排序/运算符Python3和Python2相比有挺多变化。在Python2中可以直接写一个cmp函数作为参数传入sort来自定义排
- 这个技巧将教你如何用css做出漂亮的文本按钮,有活力的按钮将节省你很多制作图片的时间,也能让你一天的工作中成为一个快乐的人,让我们一起看看效
- 本文实例讲述了Python分支语句与循环语句应用。分享给大家供大家参考,具体如下:一、分支语句1、if else语句语法:if 条件判断:
- 本文实例讲述了python的keyword模块用法。分享给大家供大家参考。具体如下:Help on module keyword:NAME
- 有一个需求是要在一个云监控的状态值中存储多个状态(包括可同时存在的各种异常、警告状态)使用了位运算机制在一个int型中存储。现在监控日志数据
- 钱包基础概念广义上,钱包是一个应用程序,为用户提供交互界面。钱包控制用户访问权限、管理比特比地址及秘钥、跟踪余额、创建交易和签名交易狭义上,
- SQL中的单记录函数 1.ASCII 返回与指定的字符对应的十进制数; SQL> select ascii('A')
- 1.join()的用法:使用前面的字符串.对后面的列表进行拼接,拼接结果是一个字符串# lst = ["alex",&q