游戏设计模式学习笔记(10)优化模式(数据局部性、脏标识、对象池、空间区分)
参考:
《设计模式与游戏完美开发》
《游戏编程模式》(https://github.com/tkchu/Game-Programming-Patterns-CN)
《图说设计模式( Graphic Design Patterns)》(https://github.com/me115/design_patterns)
【游戏设计模式】浅墨_毛星云: https://blog.csdn.net/poem_qianmo/article/details/53240330
服务定位器模式(Service Locator Pattern)详解和代码示范:https://blog.csdn.net/iefreer/article/details/9342519
数据局部性
定义
- 合理组织数据,充分使用CPU的缓存来加速内存读取。
- 现代的CPU有缓存来加速内存读取。 它可以更快地读取最近访问过的内存的毗邻内存。 通过提高内存局部性来提高性能——保证数据以处理顺序排列在连续内存上。
何时使用
- 在遇到性能问题时使用。
- 问题出在缓存不命中时使用。
应用
- 像遍历所有粒子更新的时候,可以分两个列表,一个是激活状态,一个是非激活状态,遍历更新这个激活状态就好了。而不是一个列表全部遍历再判断是否激活。
脏标识模式
定义
- 将工作延期至需要其结果时才去执行,避免不必要的工作。
- 一组原始数据随着时间变化而改变。 使用代价昂贵的过程推定一组导出数据。 用一个“脏”标识追踪导出数据是否与原始数据保持一致。 它在原始数据改变时被设置。 如果导出数据被请求时,该标识被设置了,那么重新计算并清除标识 否则的话,使用之前缓存的导出数据。
何时使用
- 原始数据的变化速度远高于导出数据的使用速度。
- 增量更新十分困难。
应用
- 像要获取一个玩家坐标,而这个坐标是经过计算转换得来,一帧内可能多个模块都要获取这个玩家坐标的时候,就会重复计算同一个值,就可以做个脏标记,这一帧获取过的时候,就存起来,后面要读直接读这个值,直到到下一帧清掉标识,或者玩家坐标外部设置手动更新清除标识。
- 或者一些每帧更新的方法,等参数变化了,才去更新。
对象池模式
定义
- 放弃单独地分配和释放对象,从固定的池中重用对象,以提高性能和内存使用率
- 定义一个池对象,其包含了一组可重用对象。 其中每个可重用对象都支持查询“使用中”状态,说明它是不是“正在使用”。 池被初始化时,它就创建了整个对象集合(通常使用一次连续的分配),然后初始化所有对象到“不在使用中”状态。
何时使用
- 需要频繁创建和销毁对象。
- 对象大小相仿。
- 在堆上进行对象内存分配十分缓慢或者会导致内存碎片。
- 每个对象都封装了像数据库或者网络连接这样很昂贵又可以重用的资源。
空间分区
定义
- 将对象根据它们的位置存储在数据结构中,来高效地定位对象。
- 对于一系列对象,每个对象都有空间上的位置。 将它们存储在根据位置组织对象的空间数据结构中,让你有效查询在某处或者某处附近的对象。 当对象的位置改变时,更新空间数据结构,这样它可以继续找到对象。
应用
- 网格是连续的桶排序。
- BSPs,k-d trees和包围盒是线性搜索树。
- 四叉树和八叉树是多叉树。