高级编程技巧 学习笔记
一、如何为创建大量实例节省内存
1.1、问题
在游戏中,定义了玩家类 player,每有一个在线玩家,在服务器内则有一个 player 的实例,当在线人数很多时,将产生大量实例(百万级)
如何降低这些大量实例的内存开销?(动态绑定属性问题)
1.2、解决方案
定义类的__slots__
属性,声明实例有哪些属性 (关闭动态绑定属性)
- 什么是动态绑定属性(
__dict__
方法实现,相当于在实例方法里添加了一个属性)
import sys
# 两个类, Player1 开启动态绑定, Player2 关闭动态绑定
class Player1(object):
def __init__(self, uid, name, status=0, level=1):
self.uid = uid
self.name = name
self.status = status
self.level = level
class Player2(object):
# 相当于实现规定了 __init__ 方法只能包含哪些属性
__slots__ = ('uid', 'name', 'status', 'level')
def __init__(self, uid, name, status=0, level=1):
self.uid = uid
self.name = name
self.status = status
self.level = level
# 实例化
p1 = Player1('0001', 'p1')
p2 = Player2('0002', 'p2')
# 开启动态绑定
p1.x = 6
p1.__dict__['y'] = 7
print(p1.__dict__)
# 关闭动态绑定, 报错
p2.y = 7
# 查看占用的内存, 发现 '动态绑定属性的操作' 所占内存多得多
print(sys.getsizeof(p1.__dict__))
print(sys.getsizeof(p1.name))
print(sys.getsizeof(p1.uid))
1.3、tracemalloc 模块
- 主要用来分析程序内存占用时使用
import sys
import tracemalloc
class Player1(object):
def __init__(self, uid, name, status=0, level=1):
self.uid = uid
self.name = name
self.status = status
self.level = level
class Player2(object):
__slots__ = ('uid', 'name', 'status', 'level')
def __init__(self, uid, name, status=0, level=1):
self.uid = uid
self.name = name
self.status = status
self.level = level
p1 = Player1('0001', 'p1')
p2 = Player2('0002', 'p2')
# # 跟踪内存的使用
tracemalloc.start()
# 分别执行以下两句
p1 = [Player1(1, 2, 3) for _ in range(100000)] # 20.6 MiB
# p2 = [Player2(1, 2, 3) for _ in range(100000)] # 7837 KiB
end = tracemalloc.take_snapshot()
# top = end.statistics('lineno') # 分析每一行代码
top = end.statistics('filename') # 分析整个文件
for stat in top[:10]:
print(stat)
来源:CSDN
作者:白菜执笔人
链接:https://blog.csdn.net/qq_43621629/article/details/104033719