用Python的 __slots__ 节省9G内存

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

这是其中一个服务器在部署代码先后的截图:
请输入图片描述
physical-memory-usage-historypython

咱们alloc了大约一百万个相似以下class的实例:web

class Image(object):
    def __init__(self, id, caption, url):
        self.id = id
        self.caption = caption
        self.url = url
        self._setup()

    # ... other methods ...

默认状况下,Python用一个dict来存储对象实例的属性。这在通常状况下还不错,并且很是灵活,乃至你在运行时能够随意设置新的属性。segmentfault

可是,对一些在”编译”前就知道该有几个固定属性的小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服务器

警告:不要贸然进行这个优化,把它用在全部地方。这种作法不利于代码维护,并且只有当你有数以千计的实例的时候才会有明显效果。优化


译注:做者在评论中关于”不利于代码维护“的说法:url

webreac:我以为slots关键字不仅是速度优化(注:这里应该是内存优化),也是类字段名的一个可靠”文档“。这有利于代码维护。为何你以为它很差?spa

Ben Hoyt(做者):有趣的说法——我不肯定应不该该把slots做为文档。不过的确是不错的注意。我以前这么说的缘由是,你须要对字段名”定义“两次(不够DRY)。namedtuple也相似。code


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

相关文章
相关标签/搜索