遇到问题:
游戏服务器的怪物数据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节省内存的字典数据结构