經過Python的__slots__節省9GB內存

咱們以前提到過,Oyster.com基於Python的web服務器緩存了大量Python字典(dicts)(哈希表(hash tables))的靜態內容。好啦,咱們最近使用一行代碼——在咱們的Image類中使用__slots__,使得每一個6GB的服務器在處理中都節省超過2GB內存。html

這是使用前和使用這一改變後再部署的RAM用量截圖:python

示意圖

咱們大概分配了一百萬個下面這個類的實例:web

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

    # ... other methods ...

Python默認使用一個字典來存儲一個對象的實例屬性。通常說來,這很不錯,並且還支持徹底動態性,好比在運行時設置任意新的屬性。緩存

然而,對於一個「小類」來講,有一些在「編譯時」就已經固定的屬性,這樣一來,字典其實是在消耗內存,在建立一百萬個這樣的類的時候,消耗更是顯而易見。你能夠跟Python說不使用字典,而是僅爲某些固定的屬性分配空間,能夠經過在類中將__slots__設置爲一個固定列表來實現這個效果:服務器

pythonclass 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,它僅限定元組空間(the space of a tuple)中的屬性可以訪問,這與在類中使用__slots__類似。可是,在我看來,從一個命名元組(namedtuple)類中繼承使人感到怪異。而且,若是你想自定義初始化器(initializer),你還必須重寫__new__而不是用__init__性能

警告:別過早優化或者將此應用在全部場景!這個方法並不利於代碼維護,並且在你真的有成千個實例的時候纔有顯著效果。優化

來自:Saving 9 GB of RAM with Python’s __slots__url

相關文章
相關標籤/搜索