用Python的 __slots__ 节省9G内存

单子春
• 阅读 8184

我们曾经提到,Oyster.com的Python web服务器怎样利用一个巨大的Python dicts(hash table),缓存大量的静态资源。我们最近在Image类中,用仅仅一行 slots 代码,让每个6G内存占用的服务进程(共4个),省出超过2G来。

这是其中一个服务器在部署代码前后的截图:
用Python的 __slots__ 节省9G内存
physical-memory-usage-history

我们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也类似。


原文:SAVING 9 GB OF RAM WITH PYTHON’S SLOTS
转载自:伯乐在线 - Kroderia

点赞
收藏
评论区
推荐文章
美凌格栋栋酱 美凌格栋栋酱
6个月前
Oracle 分组与拼接字符串同时使用
SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(
Python进阶者 Python进阶者
3年前
一文解读JavaScript中的文档对象(DOM)
大家好,我是IT共享者,人称皮皮。前言相信做网站对JavaScript再熟悉不过了,它是一门脚本语言,不同于Python的是,它是一门浏览器脚本语言,而Python则是服务器脚本语言,我们不光要会Python,还要会JavaScript,因为它对做网页方面是有很大作用的。1.文档对象(DOM)1).Document对象这是我们用的最普遍的一个文档对象了
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Karen110 Karen110
4年前
手把手教你如何在Ubuntu下安装Miniconda
前言这次我们来安排一下如何在ubuntu上安装Miniconda。这里说一下为什么不是Anaconda,因为它太占内存了,足足有5G左右,我的云服务器才40G硬盘,实在是玩不起呐。但是Anaconda和Miniconda的用法完全一摸一样,使用上不要担心,完全就是一个多装了很多包,一个少装了很多包。解释一下为什么用conda来创建python环境现在基于
Irene181 Irene181
4年前
使用Python一键删除全盘文件自动关机并留后门
/1前言/今天我们要做的案例是怎样利用Python做一个hacker软件。众所周知,一般的Hacker对于黑操作系统一般常用手法莫过于发送木马客户端,修改系统注册表。组策略,获得开机启动权限,入侵电脑然后对电脑的文件进行修改来达到不可告人的目的。今天我们要讲的就是最基础的,怎样获得开机启动,先给大家讲最基础添加文件到系统启动项的文件夹中,当然更加高端点也可
浩浩 浩浩
4年前
【Flutter实战】图片和Icon
3.5图片及ICON3.5.1图片Flutter中,我们可以通过Image组件来加载并显示图片,Image的数据源可以是asset、文件、内存以及网络。ImageProviderImageProvider是一个抽象类,主要定义了图片数据获取的接口load(),从不同的数据源获取图片需要实现不同的ImageProvi
Karen110 Karen110
4年前
25条很棒的Python一行代码,建议收藏!
自从我用Python编写第一行代码以来,就被它的简单性、出色的可读性和特别流行的一行代码所吸引。在下面,我将给大家介绍并解释一些Python一行程序。可能有些你还不知道,但对你未来的Python项目很有用。▍1、交换两个变量 a  4 b  5a,b  b,a print(a,b)  5,4让我们通过交换两个变量作为一个简
Stella981 Stella981
3年前
Python中的@函数装饰器到底是什么?
在解释@函数装饰器之前,先说一下,类中的类方法和静态方法。在Python中完全支持定义类方法、静态方法。这两种方法很相似,Python它们都使用类来调用(ps:用对象调用也可以)。区别在于:Python会自动绑定类方法的第一个参数,类方法的第一个参数会自动绑定到类本身;但对于静态方法则不会自动绑定。类方法用@classmethod
Stella981 Stella981
3年前
Python全栈快餐教程(1)
Python全栈快餐教程(1)用Flask处理HTTP请求初识FlaskFlask是最流行的Pythonweb框架之一。我们来写个最小的web应用,只有一个路由先跑进来玩玩吧。fromflaskimportFlask
Stella981 Stella981
3年前
Python中的self详细解析
!(https://imgblog.csdnimg.cn/2020042316293796.PNG)​在介绍Python的self用法之前,先来介绍下Python中的类和实例…… 我们知道,面向对象最重要的概念就是类(class)和实例(instance),类是抽象的模板,比如学生这个抽象的事物,可以用一个Student类来表示
Python进阶者 Python进阶者
1年前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这