• 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;
          }
      }
      
    }
  • 相关阅读:
    webpack基础
    LeetCode232. 用栈实现队列做题笔记
    mysql 时间加减一个月
    leetcode 1381. 设计一个支持增量操作的栈 思路与算法
    LeetCode 141. 环形链表 做题笔记
    leetcode 707. 设计链表 做题笔记
    leetcode 876. 链表的中间结点 做题笔记
    leetcode 143. 重排链表 做题笔记
    leetcode 1365. 有多少小于当前数字的数字 做题笔记
    LeetCode1360. 日期之间隔几天 做题笔记
  • 原文地址:https://www.cnblogs.com/naiking/p/2332245.html
Copyright © 2020-2023  润新知