对象池的实现
- 比较简洁的对象池
1 using System; 2 3 namespace ZSLib.ZStudio 4 { 5 public sealed class ObjectPool<T> where T : new () 6 { 7 /// <summary> 8 /// 如果需要可以增加数组的数量 9 /// </summary> 10 private int growSize = 20; 11 12 /// <summary> 13 /// 池对象 14 /// </summary> 15 private T[] pool; 16 17 /// <summary> 18 /// 指向池中元素的索引 19 /// </summary> 20 private int nextUnuseIndex = 0; 21 22 public ObjectPool(int size) 23 { 24 Resize(size, false); 25 } 26 27 public ObjectPool(int size, int growSize) 28 { 29 this.growSize = growSize; 30 Resize(size, false); 31 } 32 33 /// <summary> 34 /// 池的总大小 35 /// </summary> 36 public int Length 37 { 38 get { return pool.Length; } 39 } 40 41 /// <summary> 42 /// 池中可使用的对象 43 /// </summary> 44 public int Available 45 { 46 get { return pool.Length - nextUnuseIndex; } 47 } 48 49 /// <summary> 50 /// 池中已经分配使用对象的数量 51 /// </summary> 52 public int Spawned 53 { 54 get { return nextUnuseIndex; } 55 } 56 57 public T Spawn() 58 { 59 T inst = default(T); 60 61 // 如果需要扩大池的大小 62 if (nextUnuseIndex >= pool.Length) 63 { 64 if (growSize > 0) Resize(pool.Length + growSize, true); 65 // 无法扩大池返回default(T)-null 66 else return inst; 67 } 68 69 if (nextUnuseIndex >= 0 && nextUnuseIndex < pool.Length) 70 { 71 inst = pool[nextUnuseIndex]; 72 nextUnuseIndex++; 73 } 74 75 return inst; 76 } 77 78 public void Despawn(T inst) 79 { 80 if (nextUnuseIndex > 0) 81 { 82 nextUnuseIndex--; 83 pool[nextUnuseIndex] = inst; 84 } 85 } 86 87 /// <summary> 88 /// 快速重建池 89 /// </summary> 90 public void Reset() 91 { 92 int len = growSize; 93 if (pool != null) len = pool.Length; 94 95 Resize(len, false); 96 nextUnuseIndex = 0; 97 } 98 99 /// <summary> 100 /// 调整池的大小 101 /// </summary> 102 /// <param name="size">新的大小</param> 103 /// <param name="copyExisting">使用原有的元素</param> 104 public void Resize(int size, bool copyExisting) 105 { 106 // 提供多线程支持 107 lock (this) 108 { 109 int count = 0; 110 T[] newPool = new T[size]; 111 if (pool != null && copyExisting) 112 { 113 count = pool.Length; 114 Buffer.BlockCopy(pool, 0, newPool, 0, Math.Min(count, size)); 115 } 116 117 // 为新增加的对象初始化 118 for (int i = count; i < size; i++) 119 { 120 newPool[i] = new T(); 121 } 122 123 pool = newPool; 124 } 125 } 126 } 127 }
- 工厂模式的对象池<请参阅考Zenject>
1 using System; 2 namespace Zenject 3 { 4 public interface IMemoryPool 5 { 6 int NumTotal { get; } 7 int NumActive { get; } 8 int NumInactive { get; } 9 10 Type ItemType 11 { 12 get; 13 } 14 } 15 16 public interface IMemoryPool<TValue> : IMemoryPool 17 { 18 TValue Spawn(); 19 void Despawn(TValue item); 20 } 21 22 public interface IMemoryPool<in TParam1, TValue> : IMemoryPool 23 { 24 TValue Spawn(TParam1 param); 25 void Despawn(TValue item); 26 } 27 28 public interface IMemoryPool<in TParam1, in TParam2, TValue> : IMemoryPool 29 { 30 TValue Spawn(TParam1 param1, TParam2 param2); 31 void Despawn(TValue item); 32 } 33 34 public interface IMemoryPool<in TParam1, in TParam2, in TParam3, TValue> : IMemoryPool 35 { 36 TValue Spawn(TParam1 param1, TParam2 param2, TParam3 param3); 37 void Despawn(TValue item); 38 } 39 40 public interface IMemoryPool<in TParam1, in TParam2, in TParam3, in TParam4, TValue> : IMemoryPool 41 { 42 TValue Spawn(TParam1 param1, TParam2 param2, TParam3 param3, TParam4 param4); 43 void Despawn(TValue item); 44 } 45 46 public interface IMemoryPool<in TParam1, in TParam2, in TParam3, in TParam4, in TParam5, TValue> : IMemoryPool 47 { 48 TValue Spawn(TParam1 param1, TParam2 param2, TParam3 param3, TParam4 param4, TParam5 param5); 49 void Despawn(TValue item); 50 } 51 }
1 using System; 2 using System.Collections.Generic; 3 using ModestTree; 4 5 namespace Zenject 6 { 7 // Zero parameters 8 public class MemoryPool<TValue> : MemoryPoolBase<TValue>, IMemoryPool<TValue> 9 { 10 public TValue Spawn() 11 { 12 var item = GetInternal(); 13 Reinitialize(item); 14 return item; 15 } 16 17 protected virtual void Reinitialize(TValue item) 18 { 19 // Optional 20 } 21 } 22 23 // One parameter 24 public class MemoryPool<TParam1, TValue> 25 : MemoryPoolBase<TValue>, IMemoryPool<TParam1, TValue> 26 { 27 public TValue Spawn(TParam1 param) 28 { 29 var item = GetInternal(); 30 Reinitialize(param, item); 31 return item; 32 } 33 34 protected virtual void Reinitialize(TParam1 p1, TValue item) 35 { 36 // Optional 37 } 38 } 39 40 // Two parameters 41 public class MemoryPool<TParam1, TParam2, TValue> 42 : MemoryPoolBase<TValue>, IMemoryPool<TParam1, TParam2, TValue> 43 { 44 public TValue Spawn(TParam1 param1, TParam2 param2) 45 { 46 var item = GetInternal(); 47 Reinitialize(param1, param2, item); 48 return item; 49 } 50 51 protected virtual void Reinitialize(TParam1 p1, TParam2 p2, TValue item) 52 { 53 // Optional 54 } 55 } 56 57 // Three parameters 58 public class MemoryPool<TParam1, TParam2, TParam3, TValue> 59 : MemoryPoolBase<TValue>, IMemoryPool<TParam1, TParam2, TParam3, TValue> 60 { 61 public TValue Spawn(TParam1 param1, TParam2 param2, TParam3 param3) 62 { 63 var item = GetInternal(); 64 Reinitialize(param1, param2, param3, item); 65 return item; 66 } 67 68 protected virtual void Reinitialize(TParam1 p1, TParam2 p2, TParam3 p3, TValue item) 69 { 70 // Optional 71 } 72 } 73 74 // Four parameters 75 public class MemoryPool<TParam1, TParam2, TParam3, TParam4, TValue> 76 : MemoryPoolBase<TValue>, IMemoryPool<TParam1, TParam2, TParam3, TParam4, TValue> 77 { 78 public TValue Spawn(TParam1 param1, TParam2 param2, TParam3 param3, TParam4 param4) 79 { 80 var item = GetInternal(); 81 Reinitialize(param1, param2, param3, param4, item); 82 return item; 83 } 84 85 protected virtual void Reinitialize(TParam1 p1, TParam2 p2, TParam3 p3, TParam4 p4, TValue item) 86 { 87 // Optional 88 } 89 } 90 91 // Five parameters 92 public class MemoryPool<TParam1, TParam2, TParam3, TParam4, TParam5, TValue> 93 : MemoryPoolBase<TValue>, IMemoryPool<TParam1, TParam2, TParam3, TParam4, TParam5, TValue> 94 { 95 public TValue Spawn( 96 TParam1 param1, TParam2 param2, TParam3 param3, TParam4 param4, TParam5 param5) 97 { 98 var item = GetInternal(); 99 Reinitialize(param1, param2, param3, param4, param5, item); 100 return item; 101 } 102 103 protected virtual void Reinitialize(TParam1 p1, TParam2 p2, TParam3 p3, TParam4 p4, TParam5 p5, TValue item) 104 { 105 // Optional 106 } 107 } 108 }
1 public class Foo 2 { 3 public class Pool : MemoryPool<Foo> 4 { 5 } 6 } 7 8 public class Bar 9 { 10 readonly Foo.Pool _fooPool; 11 readonly List<Foo> _foos = new List<Foo>(); 12 13 public Bar(Foo.Pool fooPool) 14 { 15 _fooPool = fooPool; 16 } 17 18 public void AddFoo() 19 { 20 _foos.Add(_fooPool.Spawn()); 21 } 22 23 public void RemoveFoo() 24 { 25 var foo = _foos[0]; 26 _fooPool.Despawn(foo); 27 _foos.Remove(foo); 28 } 29 } 30 31 public class TestInstaller : MonoInstaller<TestInstaller> 32 { 33 public override void InstallBindings() 34 { 35 Container.Bind<Bar>().AsSingle(); 36 Container.BindMemoryPool<Foo, Foo.Pool>(); 37 } 38 }
当然也是可以抛开D/I框架来使用的.