zoukankan      html  css  js  c++  java
  • as3 性能:对象池技术

    为什么使用对象池?

    因为FLASH是托管的GC清理资源,具体什么时候清理只有GC知道,那么我们的游戏的性能就......... 

    例如:游戏里点击按钮会加载一张图片,再次点击图片,会销毁图片。

    那么如果用户不停的点击,会执行不断的加载 显示 销毁。内存就会很难控制。

    摘自Adobe的一段

    http://help.adobe.com/zh_CN/as3/mobile/WS948100b6829bd5a6-19cd3c2412513c24bce-8000.html

    请尽可能使用对象池。

    另一个重要优化称为对象池,涉及到不断重复使用对象。在初始化应用程序期间创建一定数量的对象并将其存储在一个池中,

    例如 Array 或 Vector 对象。对一个对象完成操作后,停用该对象以免它占用 CPU 资源,然后删除所有相互引用。然而,

    不要将引用设置为 null这将使它符合垃圾回收条件。只需将该对象放回到池中,在需要新对象时可以对其进行检索。

    重用对象可减少实例化对象的需求,而实例化对象成本很高。还可以减少垃圾回收器运行的机会,从而提高应用程序运行速度。 

    使用了对象池后

    我们会首先创建出需要的实例,并且把它扔进对象池objectPool

    • 对象池应该是靠单例获取
    • 开始时:初始化的时候直接给池子一定量的对象
    • 使用时:从objectPool里borrow一个
    • 归还时(释放):return它到objectPool中去
    • 完全释放:池矢量始终引用 Sprite 对象。如果要从内存中完全删除对象,需要对 SpritePool 类使用dispose()方法,从而删除所有剩余引用。
    • 所有的打算放到对象池的对象(显示对象 or 音频对象 等等)都需要继承自IPool接口
    • IPool 接口需要实现:reset() dispose()
      reset():重置对象的 这个很有必要的。当很多显示对象当return时候 都要被重置
             重置需要做的:对已经填充的数据恢复默认,对动画状态回到默认状态。总之就是让其回到刚刚构造完时的样子
      dispose():该接口主要是在彻底销毁对象池时 需要把对象池里的元素都销毁,每个元素可能会在dispose里执行以下
                 removeEventListener
                 BitmapData.dispose();
                 delete object
                 stopMovieOrSound

    1:IPoolItem.as 接口类

    package com.naiking.interfaces
    {
        /**
         * @author 醒着☆☆
         */    
        public interface IPoolItem
        {
            function reset():void;
            function dispose():void;
        }
    }

     

    2:ObjectPoolManager.as对象池管理类
    package com.naiking.manager
    {
        import com.naiking.data.HashMap;
        import com.naiking.interfaces.IPoolItem;
        
        import flash.utils.getDefinitionByName;
    
        /**
         * ObjectPoolManager
         * @醒着☆☆
         * 
         */    
        public class ObjectPoolManager
        {
            //dictionary
            private var pools:HashMap=new HashMap();
            /**
             * @param classType:ClassName String
             * @param maxSize
             */        
            public function initPool(classType:String,maxSize:int):void
            {
                //create all item by once
                trace("Created pool of "+classType);
                if(pools.containsKey(classType))
                    return;
                var itemAry:Array=[];
                pools.add(classType,itemAry);
                var cls:Class=getDefinitionByName(classType) as Class;
                for(var i:int=0;i<maxSize;i++)
                {
                    itemAry.push(new cls());
                }
            }
            public function returnItem(classType:String,item:IPoolItem):void
            {
                if(!pools.containsKey(classType))
                {
                    throw new Error("Not find:"+classType+" pool");
                    return;
                }
                trace("Give back item:"+classType);
                item.reset();
                (pools.getValue(classType) as Array).push(item);
            }
            /**
             *Get one item from pool 
             * @param classType:
             * @return 
             * 
             */        
            public function borrowItem(classType:String):IPoolItem
            {
                if(!pools.containsKey(classType))
                {
                    throw new Error("Not find:"+classType+" pool");
                    return;
                }
                if((pools.getValue(classType) as Array).length==0)
                {
                    throw new Error("The Pool:"+classType+" is full,Need expand");
                    return;
                }
                trace("Borrowed a item of"+classType);
                return (pools.getValue(classType) as Array).pop();
            }
            public function disposePool(classType:String):void
            {
                if(!pools.containsKey(classType))
                    return;
                //clear pool
                var itemAry:Array=pools.getValue(classType) as Array;
                //dispose objects in pool
                for(var i:int=0;i<itemAry.length;i++)
                {
                    /*
                    the dispose() function is used to 
                    removeEventListener、dispose Bitmapdata、delete dynamic property 
                    */
                    (itemAry[i] as IPoolItem).dispose();
                }
                itemAry=null;
                //remove this key from dictionary
                pools.remove(classType);
            }
            public function ObjectPoolManager(_sig:Sig)
            {
            }
            private  static var _instance:ObjectPoolManager;
            public static function getInstance():ObjectPoolManager
            {
                if(!_instance)
                    _instance=new ObjectPoolManager(new Sig());
                return _instance;
            }
        }
    }
    final class Sig{}

    3:HashMap.as 基本哈希表

    package com.naiking.data
    {
      import flash.utils.Dictionary;
      /**
       * 哈希图
       * @author 醒着☆☆
       *
       */
      public class HashMap
      {
          private var _length:int;
          private var _content:Dictionary;
          private var _weakKeys:Boolean;
          
          /**
           * 构造函数 
           * @param weakKeys 是否是弱引用
           * 
           */        
          public function HashMap(weakKeys:Boolean = false)
          {
              _weakKeys = weakKeys;
              _length = 0;
              _content = new Dictionary(weakKeys);
          }
          
          /**
           * 当前HashMap的长度 
           * @return 
           * 
           */        
          public function get length():int
          {
              return _length;
          }
          
          /**
           * 当前HashMap是否为空
           * @return 
           * 
           */        
          public function isEmpty():Boolean
          {
              return _length == 0;
          }
          
          /**
           * 获取Key列表 
           * @return 
           * 
           */        
          public function getKeys():Array
          {
              var temp:Array = new Array(_length);
              var index:int = 0;
              var i:*;
              for(i in _content)
              {
                  temp[index] = i;
                  index++;
              }
              return temp;
          }
          
          /**
           * 获取Value列表
           * @return 
           * 
           */        
          public function getValues():Array
          {
              var temp:Array = new Array(_length);
              var index:int = 0;
              var i:*;
              for each(i in _content)
              {
                  temp[index] = i;
                  index++;
              }
              return temp;
          }
          
          /**
           * 对Key列表中的每一项执行函数
           * @param func
           * 
           */        
          public function eachKey(func:Function):void
          {
              var i:*;
              for(i in _content)
              {
                  func(i);
              }
          }
          
          /**
           * 对Value列表中的每一项执行函数 
           * @param func
           * 
           */        
          public function eachValue(func:Function):void
          {
              var i:*;
              for each(i in _content)
              {
                  func(i);
              }
          }
          
          /**
           * 对整个HashMap的每一项执行函数
           * @param func 第一个参数是key,第二个参数是Value
           * 
           */        
          public function each2(func:Function):void
          {
              var i:*;
              for(i in _content)
              {
                  func(i,_content[i]);
              }
          }
          
          /**
           * 当前HashMap是否有value
           * @param value
           * @return 
           * 
           */        
          public function containsValue(value:*):Boolean
          {
              var i:*;
              for each(i in _content)
              {
                  if (i === value)
                  {
                      return true;
                  }
              }
              return false;
          }
          
          /**
           * 对HashMap中的每一项执行测试函数,直到获得返回 true 的项。
           * @param func 第一个参数是key,第二个参数是Value
           * @return 
           * 
           */        
          public function some(func:Function):Boolean
          {
              var i:*;
              for(i in _content)
              {
                  if(func(i,_content[i]))
                  {
                      return true;
                  }
              }
              return false;
          }
          
          /**
           * 对HashMap中的每一项执行测试函数,并构造一个新数组(值,不包含Key),其中的所有项都对指定的函数返回 true。 如果某项返回 false,则新数组中将不包含此项。 
           * @param func 第一个参数是key,第二个参数是Value
           * @return 
           * 
           */        
          public function filter(func:Function):Array
          {
              var arr:Array = [];
              var i:*;
              var v:*;
              for(i in _content)
              {
                  v = _content[i];
                  if(func(i,v))
                  {
                      arr.push(v);
                  }
              }
              return arr;
          }
          
          /**
           * 当前HashMap是否有Key
           * @param key
           * @return 
           * 
           */        
          public function containsKey(key:*):Boolean
          {
              if (_content[key] === undefined)
              {
                  return false;
              }
              return true;
          }
          
          /**
           * 从指定的Key中获取 Value
           * @param key
           * @return 
           * 
           */        
          public function getValue(key:*):*
          {
              var value:* = _content[key];
              return value === undefined ? null : value;
          }
          
          /**
           * 从指定的Value中获取Key
           * @param value
           * @return 
           * 
           */        
          public function getKey(value:*):*
          {
              var i:*;
              for(i in _content)
              {
                  if(_content[i] == value)
                  {
                      return i;
                  }
              }
              return null;
          }
          
          /**
           * 添加key value,返回的是旧的key对应的value,如果没有则返回null
           * @param key
           * @param value
           * @return
           *
           */
          public function add(key:*, value:*):*
          {
              if (key == null)
              {
                  throw new ArgumentError("cannot put a value with undefined or null key!");
                  return null;
              }
              if(value === undefined)
              {
                  return null;
              }
              else
              {
                  if (_content[key] === undefined)
                  {
                      _length++;
                  }
                  var oldValue:* = getValue(key);
                  _content[key] = value;
                  return oldValue;
              }
          }
          
          /**
           * 移除key value,返回的是旧的key对应的value,如果没有则返回null
           * @param key
           * @return
           *
           */
          public function remove(key:*):*
          {
              if (_content[key] === undefined)
              {
                  return null;
              }
              var temp:* = _content[key];
              delete _content[key];
              _length--;
              return temp;
          }
          
          /**
           * 清空当前HashMap 
           * 
           */        
          public function clear():void
          {
              _length = 0;
              _content = new Dictionary(_weakKeys);
          }
          
          /**
           * 克隆当前 HashMap
           * @return 
           * 
           */        
          public function clone():HashMap
          {
              var temp:HashMap = new HashMap(_weakKeys);
              var i:*;
              for(i in _content)
              {
                  temp.add(i, _content[i]);
              }
              return temp;
          }
          
          public function toString():String
          {
              var ks:Array = getKeys();
              var vs:Array = getValues();
              var len:int = ks.length;
              var temp:String = "HashMap Content:\n";
              var i:int;
              for(i = 0; i < len; i++)
              {
                  temp += ks[i] + " -> " + vs[i] + "\n";
              }
              return temp;
          }
      }
      
    }
  • 相关阅读:
    计算GPS点之间的距离
    C/C++ 获取系统时间 到秒 || 到毫秒
    Qt QLabel QTextBrowser 实现网址链接
    Qt QLabel 显示gif动图
    Qt QDateEdit QDateTimeEdit
    Qt QSpinBox 和 QDoubleSpinBox
    Qt QLineEdit 漂亮的搜索框 && 密码模式 && 格式化输入 && 提示文字 && 选择内容并移动 && 清除全部输入
    Qt QLabel 大小随内容自动变化 && 内容填充整个label空间
    Qt QComBox 文本框输入itemText && 文本框查找item && 本文框添加Item &&设置显示Item数量
    JSON.parse()和JSON.stringify()
  • 原文地址:https://www.cnblogs.com/naiking/p/2332245.html
Copyright © 2011-2022 走看看