flash基于对象的优化技术 黄炎中
DESCRIPTION
TRANSCRIPT
FLASH 基于对象的优化技术
盛大游戏 黄炎中
Overview• MMOG 游戏中程序的对象需求• FLASH 平台对象层面的特点• 优化办法和评测• 几个应用
MMOG 游戏中程序的对象需求• 高对象数量要求– 底层组件所需对象多 ( 图形 , 消息 , 网络 . 配置
等等 )– 游戏内容庞大,需要以对象为载体实现 – 相同类型的对象数量也很多– 对象数量增长很难预知– 对象多导致内存占用量大– 面向对象的编程方式决定了一切都要依赖对象
FLASH 平台对象层面的特点• AS3 的语言特性需要对象支持• 对象从 Object 基类集成• 对象有类型判断• 数据结构一般以对象为载体• 临时对象作为参数,也需要 new 对象• 容器 Array 和 Dictionary 中存储的是数值或者对象• 使用引用来控制对象和属性• 对象由底层控制其回收 (GC 操作 )
• AS3 语言特点的代价– 必须通过引用来控制对象– 单个对象占资源量大– GC 操作无法控制– 类型判断可有可无– 属性访问有性能开销
优化办法• 使用属性级的并联• 例:需要实现以个 Unit 列表,每个元素都
是一个 Unit 结构 public class Unit{ public var nShape:int; public var nX:int;
Public var nY:int;
} ;
• Version1:public class UnitArray{
private var m_UnitArr:Array;public UnitArray(num:int) // 构造函数{ m_UnitArr = new Array; for(var i:int = 0 ; i < num ; i++) { m_UnitArr[i]=new Unit; }}// 使用索引访问对象属性public var GetUnit(idx:int):Unit{ return m_UnitArr[idx]; }
}
假设包含 10000 个 UNIT 那么系统中保存的对象数量是 100001 个 (Num+1 个 )增加 UNIT 将改变对象数量
• Version2public class UnitArray
{ public static const ATTR_SHAPE=0; public static const ATTR_X=1; public static const ATTR_Y=2;
private var nShapeArr:Array; private var nXArr:Array; private var nYArr:Array;
public UnitArray(num:int) // 构造函数{
nShapeArr = new Array(num); nXArr = new Array(num);
nYArr = new Array(num);}……// 使用索引访问对象属性public function Get/SetShape(idx:uint,value:int);public function Get/SetX(idx:uint,value:int);public function Get/SetY(idx:uint,value:int);
}
这种情况下 表示同样的数据内容对象开销仅为 ( 属性数量 +1)增加一个 UNIT 并不改变总对象数量
• Version3public class UnitArray
{ public static const ATTR_SHAPE:int =0; public static const ATTR_X:int =1; public static const ATTR_Y:int =2; public static const ATTR_MAX:int = 3;
private var nAttrMap:Array=new Array[ATTR_MAX];
public UnitArray(num:int) // 构造函数{
for(var i:int = 0;i<ATTR_MAX;i++) { nAttrMap[i]=new Array(num); }}……// 使用索引访问对象属性public function GetAttr (idx:uint,Attr:int):int;public function SetAttr (idx:uint,Attr:int,value:int):void;
}– 这种情况下调整了对象访问形式可以更简单的组织数据
• UnitArray 的本质
索引 nShape nX nY
0 1 500 500
1 2 432 324
2 3 113 321
3 3 567 212
4 2 323 433
5 1 211 12
….
串行属性存储表示方法
并列属性存储表示
对象的本质是属性的集合,通过改变表示方式来构造对象
• 这种方法的使用条件– 1 对象数量极多– 2 对象属性总数必须比对象数量要少– 3 放弃类型判断– 4 适当调整访问形式– 5 访问对象的形式可以用 ID 表示– 6 带有 FreeList 性质的对象也可以使用
• 你可以获得的好处– 1 用更少的内存达到相同目标– 2 提高访问速度
• 性能测试– 性能测试方式:– 建立以个可以表示 100000 个对象的列表
• 结论是 VERSION2 比 VERSION1 占用更少的资源达到同样的目标。• VERSION2 是访问单个数组对象的操作• VERSION1 是访问单个数组对象后,还需要访问里面
的属性。操作上多一步。
普通方法 并联方法对象数 100009 10
访问速度 920ms 760ms
几种应用场合• 基于 MAP+TILE 结构的地图– MAP 数据将包含 WIDTH*HEIGHT 数据量的 对
象• 如果 Width=200,Height = 100 那就需要 20000 个对象。• 但是如果用并联形式,对象数量只依赖于 Map 单元
格的属性数。大大降低对象的数量和访问速度
• GUI 系统– GUI 系统是将每个控件的属性统一并联化,通
过自定义实现的多组方法,来控制统一的属性。从而达到不同的表现。
– 比如对同一个 GUI 对象来说,可以通过判断其属性 Type 获得交互方式,渲染方式等内容。
– 并且一个控件不使用时,可以通过标记某个属性来进行资源回收。
• MMO 中的玩家属性– MMORPG 中的玩家属性,是由服务器控制的。– 玩家的消失和出现,会带有明显的资源释放和
申请操作。资源流动量也比较大。会降低性能。– 并联方法只要属性数量 < 同屏玩家数,就可以
使用这种方法。
• 粒子系统– 每个粒子数据结构相同。但是传统方法中,新
建立一个粒子需要 NEW 一个对象。当粒子很多的时候,对象的出生和销毁将是个严重的负担。
– 使用并联属性方法后,同样的效果,不会增加任何内存开销。并且有更快的速度
总结• 基于并联属性的对象优化技巧可以让程序
以更小的开销达到相同的效果。同时也在一定程度上解决了 FLASH 对象数量无法控制和 GC 回收难以控制的问题。
• 但是这对程序编写者本人也提出了更高的要求。如果用的好,将对程序有很大的帮助。
• 谢谢大家