zoukankan      html  css  js  c++  java
  • 对象池 object pool

    对象池适用于:

    • 对象的创建很耗时
    • 对象频繁地释放再创建

    对象池的实现:将释放的对象放进对象池中,在新建对象时,从对象池取对象

    public class ObjectPool<T> where T : class, new()
    {
        private Stack<T> m_objectStack = new Stack<T>();
    
        public T New()
        {
            return (m_objectStack.Count == 0) ? new T() : m_objectStack.Pop();
        }
    
        public void Store(T t)
        {
            m_objectStack.Push(t);
        }
    }

    改进第一步:对象被重新使用前,reset所有的成员变量。

    public class ObjectPool<T> where T : class, new()
    {
        private Stack<T> m_objectStack;
    
        private Action<T> m_resetAction; //indicate whether need reset
        private Action<T> m_onetimeInitAction; //indicate whether need initialize
    
        public ObjectPool(int initialBufferSize, Action<T>
            ResetAction = null, Action<T> OnetimeInitAction = null)
        {
            m_objectStack = new Stack<T>(initialBufferSize);
            m_resetAction = ResetAction;
            m_onetimeInitAction = OnetimeInitAction;
        }
    
        public T New()
        {
            if (m_objectStack.Count > 0)
            {
                T t = m_objectStack.Pop();
    
                if (m_resetAction != null)
                    m_resetAction(t);
    
                return t;
            }
            else
            {
                T t = new T();
    
                if (m_onetimeInitAction != null)
                    m_onetimeInitAction(t);
    
                return t;
            }
        }
    
        public void Store(T obj)
        {
            m_objectStack.Push(obj);
        }
    }

    参数T被指明为”where T:class,new()”,意味着有两个限制。首先,T必须为一个类(毕竟,只有引用类型需要被obejct-pool);其次,它必须要有一个无参构造函数。

    以下是池的使用方法:

    class SomeClass : MonoBehaviour
    {
        private ObjectPool<List<Vector3>> m_poolOfListOfVector3 =
            //32为假设的最大数量
            new ObjectPool<List<Vector3>>(32,
            (list) => {
                list.Clear();
            },
            (list) => {
                //初始化容量为1024
                list.Capacity = 1024;
            });
    
        void Update()
        {
            List<Vector3> listVector3 = m_poolOfListOfVector3.New();
    
            // do stuff
    
            m_poolOfListOfVector3.Store(listVector3);
        }
    }

    改进第二步:允许一次性回收所有已经池化的对象

    public class ObjectPoolWithCollectiveReset<T> where T : class, new()
    {
        private List<T> m_objectList; //Stack<T>被List<T>代替,可以跟踪最近创建或释放的对象在list中索引
        private int m_nextAvailableIndex = 0;
    
        private Action<T> m_resetAction;
        private Action<T> m_onetimeInitAction;
    
        public ObjectPoolWithCollectiveReset(int initialBufferSize, Action<T>
            ResetAction = null, Action<T> OnetimeInitAction = null)
        {
            m_objectList = new List<T>(initialBufferSize);
            m_resetAction = ResetAction;
            m_onetimeInitAction = OnetimeInitAction;
        }
    
        public T New()
        {
            if (m_nextAvailableIndex < m_objectList.Count)
            {
                // an allocated object is already available; just reset it
                T t = m_objectList[m_nextAvailableIndex];
                m_nextAvailableIndex++;
    
                if (m_resetAction != null)
                    m_resetAction(t);
    
                return t;
            }
            else
            {
                // no allocated object is available
                T t = new T();
                m_objectList.Add(t);
                m_nextAvailableIndex++;
    
                if (m_onetimeInitAction != null)
                    m_onetimeInitAction(t);
    
                return t;
            }
        }
    
        public void ResetAll() //原本的store()
        {
           //重置索引
            m_nextAvailableIndex = 0;
        }
    }

    局限:显然,当我们需要一个其它类型的对象池时就需要重新申明一个。或许我们可以实现一个对用户透明。创建管理所有类型池的ObjectPool。

  • 相关阅读:
    在vue项目中引用element-ui时 让el-input 获取焦点的方法
    vue cli 平稳升级webapck4
    如何在 vuex action 中获取到 vue 实例
    Vue主要原理最简实现与逻辑梳理
    vue自定义指令clickoutside扩展--多个元素的并集作为inside
    关于使用element中的popup问题
    教你如何检查一个函数是否为JavaScript运行时环境内建函数
    用 Vue 做一个简单的购物app
    vue 手机键盘把底部按钮顶上去
    基于Linux的智能家居的设计(2)
  • 原文地址:https://www.cnblogs.com/qionglouyuyu/p/5015166.html
Copyright © 2011-2022 走看看