Python内存优化,节省内存字典ConstDict

   遇到问题:

        游戏服务器的怪物数据monsterdata.py 用字典表示,怪物字典数据基本做取值和修改处理,不额外增加字段,py文件大小100m,想办法节省内存,根据特点,不使用原生的dict数据结构,用ConstDict是去代替,内存节省到50m左右。

ConstDict

python代替的dict数据结构

若字典不会增加字段,只读/原字段修改
使用ConstDict可节省内存

dict()内存主要消耗的地方:

1、dict扩容机制,预留内存空间
2、dict也是一个对象,内部会动态维护__dict__,增加slot类属性可以节省内容

节省内存大小:一半左右,字段越大节省越多

适用场景:需要生成大量的静态字典场景

缺点:根据字典的属性,需要先生成类,再生成对象

python版本:python2.7

例子代码:

>>> test_dic = {
...     "m_HP": 1,
...     "m_MP": 2,
...     "m_Attack": 3,
...     "m_Defense": 4,
...     "m_Speed": 5,
...     "m_Dodge": 6,
...     "m_Hit": 7,
...     "m_Double": 8,
... }
>>>
>>> class MonsterDict(constdict.ConstDict):
...     __slots__ = test_dic.keys()
    

>>> const_dic = MonsterDict(test_dic)
>>> print(asizesof(test_dic))
(1192,)
>>> print(asizesof(const_dic))
(584,)


>>> print(const_dic)
{'m_Defense': 4, 'm_Speed': 5, 'm_Hit': 7, 'm_Double': 8, 'm_Attack': 3, 'm_HP': 1, 'm_Dodge': 6, 'm_MP': 2}


>>> print(const_dic.keys())
['m_HP', 'm_Defense', 'm_Speed', 'm_Attack', 'm_Dodge', 'm_MP', 'm_Hit', 'm_Double']


>>> print(const_dic.values())
[1, 4, 5, 3, 6, 2, 7, 8]


>>> const_dic["m_Dodge"] = 12456
>>> print(const_dic["m_Dodge"])
12456


>>> print(const_dic.iteritems())
<generator object <genexpr> at 0x00000000094FA2C8>

ConstDict.py 代码:

# -*- coding: utf-8 -*-


class ConstDict(object):
    def __init__(self, dic):
        for key, val in dic.iteritems():
            setattr(self, key, val)

    def __iter__(self):
        return iter(self.__slots__)

    def __getitem__(self, item):
        return getattr(self, item, None)

    def __setitem__(self, key, value):
        return setattr(self, key, value)
    
    def __contains__(self, item):
        try:
            return getattr(self, item, False)
        except:
            return False
        
    def get(self, key, default):
        return getattr(self, key, default)

    def iteritems(self):
        return ((key, getattr(self, key, None)) for key in self.__slots__)

    def items(self):
        return [(key, getattr(self, key, None)) for key in self.__slots__]

    def iterkeys(self):
        return iter(self.__slots__)

    def itervalues(self):
        return (getattr(self, key, None) for key in self.__slots__)

    def keys(self):
        return self.__slots__

    def values(self):
        return [getattr(self, key, None) for key in self.__slots__]
    
    def update(self, dic):
        """
        const dict noly support exist keys update
        """
        for key, val in dic.iteritems():
            if getattr(self, key, False):
                setattr(self, key, val)
        raise NotImplementedError("ConstDictBase not support update")
    
    def __str__(self):
        return str(dict(self.items()))

代码优化维护会在gitbub更新

github:GitHub - Grente/ConstDict: python节省内存的字典数据结构

上一篇:第一个只出现一次的字符位置


下一篇:Python字典的作用与基本操作