cs
using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Threading;
using UnityEngine;
using UnityEngine.Profiling;
namespace ILGame
{
#region 核心接口和抽象类
/// <summary>
/// 池化对象接口
/// </summary>
public interface IPoolable
{
/// <summary>
/// 对象被租借时的初始化方法
/// </summary>
void OnPoolRent();
/// <summary>
/// 对象被返回时的重置方法
/// </summary>
void OnPoolReturn();
}
/// <summary>
/// 泛型池策略接口
/// </summary>
public interface IPoolPolicy<T> where T : class
{
/// <summary>
/// 创建新对象
/// </summary>
T Create();
/// <summary>
/// 对象被租借时的初始化
/// </summary>
void OnRent(T item);
/// <summary>
/// 对象被返回时的重置
/// </summary>
void OnReturn(T item);
/// <summary>
/// 对象被销毁时的清理
/// </summary>
void OnDestroy(T item);
}
#endregion
#region 协程助手类
/// <summary>
/// 协程管理器(用于处理延迟回收)
/// </summary>
public class CoroutineManager : MonoBehaviour
{
private static CoroutineManager _instance;
public static CoroutineManager Instance
{
get
{
if (_instance == null)
{
var go = new GameObject("CoroutineManager");
_instance = go.AddComponent<CoroutineManager>();
if (Application.isPlaying)
{
UnityEngine.Object.DontDestroyOnLoad(go);
}
}
return _instance;
}
}
/// <summary>
/// 启动协程
/// </summary>
public new Coroutine StartCoroutine(IEnumerator routine)
{
return base.StartCoroutine(routine);
}
/// <summary>
/// 停止协程
/// </summary>
public new void StopCoroutine(Coroutine routine)
{
base.StopCoroutine(routine);
}
}
#endregion
#region 支持自定义初始化的引用类型对象池
/// <summary>
/// 高度优化的引用类型对象池(支持自定义初始化)
/// </summary>
public sealed class HyperPool<T> : IDisposable where T : class
{
#region 配置
private readonly IPoolPolicy<T> _policy;
private readonly int _initialCapacity;
private readonly int _maxCapacity;
private readonly bool _allowExpand;
// 自定义初始化器缓存
private readonly List<Action<T>> _onRentCallbacks = new List<Action<T>>();
private readonly List<Action<T>> _onReturnCallbacks = new List<Action<T>>();
#endregion
#region 核心数据结构
private readonly Stack<T> _availableStack;
private readonly HashSet<T> _allObjects;
private readonly List<T> _activeObjects;
private readonly object _poolLock = new object();
// 线程本地缓存
[ThreadStatic]
private static ThreadLocalCache _threadLocalCache;
#endregion
#region 统计字段(改为字段而不是属性)
private int _totalCreated = 0;
private int _activeCount = 0;
private int _rentCount = 0;
private int _returnCount = 0;
private int _peakCount = 0;
// 公共属性
public int TotalCount
{
get
{
lock (_poolLock)
{
return _allObjects.Count;
}
}
}
public int ActiveCount
{
get
{
return _activeCount;
}
}
public int AvailableCount
{
get
{
int threadLocalCount = 0;
if (_threadLocalCache != null)
{
threadLocalCount = _threadLocalCache.Count;
}
lock (_poolLock)
{
return _availableStack.Count + threadLocalCount;
}
}
}
public int PeakCount { get { return _peakCount; } }
public int RentCount { get { return _rentCount; } }
public int ReturnCount { get { return _returnCount; } }
#endregion
#region 构造函数
/// <summary>
/// 创建对象池
/// </summary>
public HyperPool(
IPoolPolicy<T> policy = null,
int initialCapacity = 32,
int maxCapacity = 1024,
bool allowExpand = true)
{
_policy = policy != null ? policy : CreateDefaultPolicy();
_initialCapacity = Math.Max(initialCapacity, 1);
_maxCapacity = maxCapacity > 0 ? maxCapacity : int.MaxValue;
_allowExpand = allowExpand;
_availableStack = new Stack<T>(_initialCapacity);
_allObjects = new HashSet<T>();
_activeObjects = new List<T>(_initialCapacity);
Prewarm(_initialCapacity);
}
/// <summary>
/// 创建带初始化器的对象池
/// </summary>
public HyperPool(
Action<T> onRent = null,
Action<T> onReturn = null,
Func<T> factory = null,
Action<T> onDestroy = null,
int initialCapacity = 32,
int maxCapacity = 1024)
: this(CreatePolicyWithCallbacks(onRent, onReturn, factory,onDestroy), initialCapacity, maxCapacity)
{
}
#endregion
#region 核心方法
/// <summary>
/// 租借对象
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public T Rent()
{
Profiler.BeginSample("HyperPool.Rent");
T item = GetItem();
if (item == null)
{
Profiler.EndSample();
return null;
}
InitializeItem(item);
TrackItem(item);
// 使用字段而不是属性
Interlocked.Increment(ref _rentCount);
// 更新峰值计数
int currentActive = Interlocked.Increment(ref _activeCount);
int currentPeak = _peakCount;
while (currentActive > currentPeak)
{
int oldPeak = Interlocked.CompareExchange(ref _peakCount, currentActive, currentPeak);
if (oldPeak == currentPeak)
break;
currentPeak = oldPeak;
}
Profiler.EndSample();
return item;
}
/// <summary>
/// 租借对象并应用自定义初始化
/// </summary>
public T Rent(Action<T> initializer)
{
var item = Rent();
if (item != null && initializer != null)
{
initializer(item);
}
return item;
}
/// <summary>
/// 返回对象到池中
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Return(T item)
{
if (item == null) return;
Profiler.BeginSample("HyperPool.Return");
lock (_poolLock)
{
if (!_allObjects.Contains(item))
{
// 不属于此池的对象,直接丢弃
_policy.OnDestroy(item);
Profiler.EndSample();
return;
}
}
ResetItem(item);
ReleaseItem(item);
// 使用字段而不是属性
Interlocked.Increment(ref _returnCount);
Interlocked.Decrement(ref _activeCount);
Profiler.EndSample();
}
/// <summary>
/// 延迟返回对象到池中
/// </summary>
public void Return(T item, float delaySeconds)
{
if (item == null || delaySeconds <= 0) return;
CoroutineManager.Instance.StartCoroutine(DelayedReturnCoroutine(item, delaySeconds));
}
/// <summary>
/// 安全使用对象(自动返回)
/// </summary>
public TResult Use<TResult>(Func<T, TResult> func)
{
var item = Rent();
try
{
return func(item);
}
finally
{
Return(item);
}
}
/// <summary>
/// 安全使用对象(无返回值)
/// </summary>
public void Use(Action<T> action)
{
var item = Rent();
try
{
action(item);
}
finally
{
Return(item);
}
}
#endregion
#region 私有方法
private T GetItem()
{
// 1. 检查线程本地缓存
if (_threadLocalCache != null && _threadLocalCache.Count > 0)
{
return _threadLocalCache.Pop();
}
// 2. 检查主池
lock (_poolLock)
{
if (_availableStack.Count > 0)
{
return _availableStack.Pop();
}
}
// 3. 创建新对象(如果允许)
if (_allowExpand)
{
lock (_poolLock)
{
if (_allObjects.Count < _maxCapacity)
{
Interlocked.Increment(ref _totalCreated);
return CreateNewItem();
}
}
}
return null;
}
private void InitializeItem(T item)
{
// 调用策略初始化
_policy.OnRent(item);
// 调用自定义回调
for (int i = 0; i < _onRentCallbacks.Count; i++)
{
_onRentCallbacks[i](item);
}
}
private void ResetItem(T item)
{
// 调用策略重置
_policy.OnReturn(item);
// 调用自定义回调
for (int i = 0; i < _onReturnCallbacks.Count; i++)
{
_onReturnCallbacks[i](item);
}
}
private void TrackItem(T item)
{
lock (_poolLock)
{
_activeObjects.Add(item);
}
}
private void ReleaseItem(T item)
{
// 从活跃列表中移除
lock (_poolLock)
{
_activeObjects.Remove(item);
}
// 尝试放入线程本地缓存
if (_threadLocalCache == null)
{
_threadLocalCache = new ThreadLocalCache();
}
if (!_threadLocalCache.TryPush(item))
{
// 线程本地缓存已满,放入主池
lock (_poolLock)
{
_availableStack.Push(item);
}
}
}
private T CreateNewItem()
{
var item = _policy.Create();
lock (_poolLock)
{
_allObjects.Add(item);
}
return item;
}
private System.Collections.IEnumerator DelayedReturnCoroutine(T item, float delaySeconds)
{
yield return new WaitForSeconds(delaySeconds);
Return(item);
}
#endregion
#region 辅助方法
/// <summary>
/// 预暖池
/// </summary>
public void Prewarm(int count)
{
lock (_poolLock)
{
int toCreate = Math.Min(count, _maxCapacity - _allObjects.Count);
for (int i = 0; i < toCreate; i++)
{
Interlocked.Increment(ref _totalCreated);
var item = CreateNewItem();
_availableStack.Push(item);
}
}
}
/// <summary>
/// 清理池(保留指定数量的对象)
/// </summary>
public void Shrink(int keepCount)
{
lock (_poolLock)
{
// 清理线程本地缓存
if (_threadLocalCache != null)
{
_threadLocalCache.Clear();
}
// 清理可用对象
while (_availableStack.Count > keepCount && _availableStack.Count > 0)
{
var item = _availableStack.Pop();
_allObjects.Remove(item);
_policy.OnDestroy(item);
}
}
}
/// <summary>
/// 添加租借时的回调
/// </summary>
public void AddRentCallback(Action<T> callback)
{
if (callback != null && !_onRentCallbacks.Contains(callback))
{
_onRentCallbacks.Add(callback);
}
}
/// <summary>
/// 添加返回时的回调
/// </summary>
public void AddReturnCallback(Action<T> callback)
{
if (callback != null && !_onReturnCallbacks.Contains(callback))
{
_onReturnCallbacks.Add(callback);
}
}
/// <summary>
/// 获取统计信息
/// </summary>
public string GetStats()
{
int totalCount = TotalCount;
int availableCount = AvailableCount;
int rentCount = _rentCount;
double hitRate = rentCount > 0
? (double)(rentCount - (_totalCreated - availableCount)) / rentCount * 100.0
: 0.0;
return string.Format("HyperPool<{0}>: Total={1}, Active={2}, Available={3}, Peak={4}, HitRate={5:F1}%",
typeof(T).Name, totalCount, ActiveCount, availableCount, PeakCount, hitRate);
}
public void Dispose()
{
lock (_poolLock)
{
// 清理所有对象
foreach (var item in _allObjects)
{
_policy.OnDestroy(item);
}
_allObjects.Clear();
_activeObjects.Clear();
_availableStack.Clear();
_onRentCallbacks.Clear();
_onReturnCallbacks.Clear();
}
if (_threadLocalCache != null)
{
_threadLocalCache.Clear();
}
}
#endregion
#region 策略创建辅助方法
private static IPoolPolicy<T> CreateDefaultPolicy()
{
return new DynamicPolicy<T>(null, null, null,null);
}
private static IPoolPolicy<T> CreatePolicyWithCallbacks(Action<T> onRent, Action<T> onReturn, Func<T> factory = null, Action<T> onDestroy = null)
{
return new DynamicPolicy<T>(factory, onRent, onReturn,onDestroy);
}
#endregion
#region 内部类
/// <summary>
/// 动态策略(支持无参构造函数或自定义工厂)
/// </summary>
private class DynamicPolicy<TItem> : IPoolPolicy<TItem> where TItem : class
{
private readonly Func<TItem> _factory;
private readonly Action<TItem> _onRent;
private readonly Action<TItem> _onReturn;
private readonly Action<TItem> _onDestroy;
public DynamicPolicy(Func<TItem> factory = null, Action<TItem> onRent = null, Action<TItem> onReturn = null,Action<TItem> onDestroy = null)
{
_factory = factory ?? CreateDefaultFactory();
_onRent = onRent;
_onReturn = onReturn;
_onDestroy = onDestroy;
}
public TItem Create()
{
return _factory();
}
public void OnRent(TItem item)
{
if (_onRent != null) _onRent(item);
}
public void OnReturn(TItem item)
{
if (_onReturn != null) _onReturn(item);
}
public void OnDestroy(TItem item)
{
if (_onDestroy != null) _onDestroy(item);
}
private static Func<TItem> CreateDefaultFactory()
{
// 尝试使用 Activator.CreateInstance
try
{
// 检查是否有无参构造函数
var constructor = typeof(TItem).GetConstructor(Type.EmptyTypes);
if (constructor != null)
{
return () => Activator.CreateInstance<TItem>();
}
}
catch
{
// 忽略错误
}
// 如果没有无参构造函数,检查是否实现 IPoolable 接口
if (typeof(IPoolable).IsAssignableFrom(typeof(TItem)))
{
// 尝试使用反射创建
return () =>
{
try
{
var obj = Activator.CreateInstance(typeof(TItem)) as TItem;
if (obj == null)
{
throw new InvalidOperationException(
string.Format("Cannot create instance of type {0}. Please provide a custom factory method.",
typeof(TItem).Name));
}
return obj;
}
catch (Exception ex)
{
throw new InvalidOperationException(
string.Format("Cannot create instance of type {0}. Please provide a custom factory method. Error: {1}",
typeof(TItem).Name, ex.Message));
}
};
}
// 最后的手段:抛出异常
return () => {
throw new InvalidOperationException(
string.Format("Type {0} does not have a parameterless constructor and no custom factory was provided.",
typeof(TItem).Name));
};
}
}
/// <summary>
/// 线程本地缓存
/// </summary>
private class ThreadLocalCache
{
private const int CacheSize = 8;
private readonly T[] _cache;
private int _count;
public int Count { get { return _count; } }
public ThreadLocalCache()
{
_cache = new T[CacheSize];
_count = 0;
}
public T Pop()
{
if (_count == 0) return null;
_count--;
var item = _cache[_count];
_cache[_count] = null;
return item;
}
public bool TryPush(T item)
{
if (_count >= CacheSize) return false;
_cache[_count] = item;
_count++;
return true;
}
public void Clear()
{
for (int i = 0; i < _count; i++)
{
_cache[i] = null;
}
_count = 0;
}
}
#endregion
}
#endregion
#region Unity Component对象池(特别优化)
/// <summary>
/// Unity Component对象池(支持Transform、位置等)
/// </summary>
public class UnityComponentPool<T> : IDisposable where T : Component
{
private readonly HyperPool<T> _objectPool;
private readonly T _prefab;
private readonly Transform _parent;
public int TotalCount { get { return _objectPool.TotalCount; } }
public int ActiveCount { get { return _objectPool.ActiveCount; } }
public int AvailableCount { get { return _objectPool.AvailableCount; } }
public UnityComponentPool(
T prefab,
Transform parent = null,
int initialCapacity = 10,
int maxCapacity = 100,
Action<T> onRent = null,
Action<T> onReturn = null)
{
if (prefab == null)
throw new ArgumentNullException("prefab");
_prefab = prefab;
_parent = parent;
var policy = new UnityComponentPolicy<T>(prefab, parent);
if (onRent != null) policy.AddRentCallback(onRent);
if (onReturn != null) policy.AddReturnCallback(onReturn);
_objectPool = new HyperPool<T>(
policy,
initialCapacity,
maxCapacity
);
}
/// <summary>
/// 租借Component
/// </summary>
public T Rent()
{
return _objectPool.Rent();
}
/// <summary>
/// 租借Component并设置位置/旋转
/// </summary>
public T Rent(Vector3 position, Quaternion rotation, Transform parent = null)
{
var component = Rent();
if (component != null)
{
var transform = component.transform;
transform.position = position;
transform.rotation = rotation;
if (parent != null)
{
transform.SetParent(parent, false);
}
else if (_parent != null)
{
transform.SetParent(_parent, false);
}
}
return component;
}
/// <summary>
/// 返回Component
/// </summary>
public void Return(T component)
{
_objectPool.Return(component);
}
/// <summary>
/// 延迟返回Component
/// </summary>
public void Return(T component, float delaySeconds)
{
_objectPool.Return(component, delaySeconds);
}
/// <summary>
/// 预暖池
/// </summary>
public void Prewarm(int count)
{
_objectPool.Prewarm(count);
}
/// <summary>
/// 获取统计信息
/// </summary>
public string GetStats()
{
return string.Format("UnityComponentPool<{0}>: {1}", typeof(T).Name, _objectPool.GetStats());
}
public void Dispose()
{
_objectPool.Dispose();
}
}
/// <summary>
/// Unity Component策略
/// </summary>
public class UnityComponentPolicy<T> : IPoolPolicy<T> where T : Component
{
private readonly T _prefab;
private readonly Transform _parent;
private readonly List<Action<T>> _onRentCallbacks = new List<Action<T>>();
private readonly List<Action<T>> _onReturnCallbacks = new List<Action<T>>();
public UnityComponentPolicy(T prefab, Transform parent = null)
{
_prefab = prefab;
_parent = parent;
}
public T Create()
{
T component;
if (_parent != null)
{
component = UnityEngine.Object.Instantiate(_prefab, _parent);
}
else
{
component = UnityEngine.Object.Instantiate(_prefab);
}
component.gameObject.SetActive(false);
component.gameObject.name = string.Format("{0}_Pooled_{1}",
_prefab.name, Guid.NewGuid().ToString("N").Substring(0, 8));
return component;
}
public void OnRent(T item)
{
if (item != null)
{
item.gameObject.SetActive(true);
}
for (int i = 0; i < _onRentCallbacks.Count; i++)
{
_onRentCallbacks[i](item);
}
}
public void OnReturn(T item)
{
if (item != null && item.gameObject != null)
{
item.gameObject.SetActive(false);
// 重置到池父节点
if (_parent != null)
{
item.transform.SetParent(_parent, false);
}
}
for (int i = 0; i < _onReturnCallbacks.Count; i++)
{
_onReturnCallbacks[i](item);
}
}
public void OnDestroy(T item)
{
if (item != null)
{
if (Application.isPlaying)
UnityEngine.Object.Destroy(item.gameObject);
else
UnityEngine.Object.DestroyImmediate(item.gameObject);
}
}
public void AddRentCallback(Action<T> callback)
{
if (callback != null && !_onRentCallbacks.Contains(callback))
{
_onRentCallbacks.Add(callback);
}
}
public void AddReturnCallback(Action<T> callback)
{
if (callback != null && !_onReturnCallbacks.Contains(callback))
{
_onReturnCallbacks.Add(callback);
}
}
}
#endregion
#region 对象池管理器(全局管理)
/// <summary>
/// 全局对象池管理器
/// </summary>
public static class PoolManager
{
private static readonly Dictionary<Type, object> _pools = new Dictionary<Type, object>();
private static readonly Dictionary<string, object> _namedPools = new Dictionary<string, object>();
private static readonly object _globalLock = new object();
private static Transform _poolRoot;
/// <summary>
/// 池根节点
/// </summary>
public static Transform PoolRoot
{
get
{
if (_poolRoot == null)
{
var go = new GameObject("PoolManager_Root");
if (Application.isPlaying)
{
UnityEngine.Object.DontDestroyOnLoad(go);
}
_poolRoot = go.transform;
}
return _poolRoot;
}
}
/// <summary>
/// 获取或创建泛型对象池(带自定义工厂)
/// </summary>
public static HyperPool<T> GetPool<T>(
Action<T> onRent = null,
Action<T> onReturn = null,
Func<T> factory = null,
Action<T> onDestroy = null,
string poolName = null,
int initialCapacity = 32,
int maxCapacity = 1024) where T : class
{
if (poolName != null)
{
lock (_globalLock)
{
if (_namedPools.ContainsKey(poolName))
{
var pool = _namedPools[poolName];
if (pool is HyperPool<T> typedPool)
{
return typedPool;
}
}
var newPool = new HyperPool<T>(onRent, onReturn, factory, onDestroy, initialCapacity, maxCapacity);
_namedPools[poolName] = newPool;
return newPool;
}
}
var type = typeof(T);
lock (_globalLock)
{
if (_pools.ContainsKey(type))
{
var pool = _pools[type];
if (pool is HyperPool<T> typedPool)
return typedPool;
}
var newPool = new HyperPool<T>(onRent, onReturn, factory, onDestroy, initialCapacity, maxCapacity);
_pools[type] = newPool;
return newPool;
}
}
/// <summary>
/// 获取或创建Unity Component对象池
/// </summary>
public static UnityComponentPool<T> GetUnityPool<T>(
T prefab,
string poolName = null,
Transform parent = null,
int initialCapacity = 10,
int maxCapacity = 100,
Action<T> onRent = null,
Action<T> onReturn = null) where T : Component
{
string finalPoolName;
if (poolName != null)
{
finalPoolName = poolName;
}
else
{
finalPoolName = string.Format("{0}_{1}", typeof(T).Name, prefab.name);
}
lock (_globalLock)
{
if (_namedPools.ContainsKey(finalPoolName))
{
var pool = _namedPools[finalPoolName];
if (pool is UnityComponentPool<T> typedPool)
{
return typedPool;
}
}
Transform poolParent;
if (parent != null)
{
poolParent = parent;
}
else
{
poolParent = CreatePoolParent(finalPoolName);
}
var newPool = new UnityComponentPool<T>(
prefab,
poolParent,
initialCapacity,
maxCapacity,
onRent,
onReturn
);
_namedPools[finalPoolName] = newPool;
return newPool;
}
}
/// <summary>
/// 回收对象到默认池
/// </summary>
public static void Return<T>(T item, string poolName = null) where T : class
{
if (item == null) return;
if (poolName != null)
{
lock (_globalLock)
{
if (_namedPools.ContainsKey(poolName))
{
var poolObj = _namedPools[poolName];
if (poolObj is HyperPool<T> pool)
{
pool.Return(item);
}
}
}
}
else
{
var type = typeof(T);
lock (_globalLock)
{
if (_pools.ContainsKey(type))
{
var poolObj = _pools[type];
if (poolObj is HyperPool<T> pool)
{
pool.Return(item);
}
}
}
}
}
/// <summary>
/// 延迟回收对象到默认池
/// </summary>
public static void Return<T>(T item, float delaySeconds, string poolName = null) where T : class
{
if (item == null || delaySeconds <= 0) return;
if (poolName != null)
{
lock (_globalLock)
{
if (_namedPools.ContainsKey(poolName))
{
var poolObj = _namedPools[poolName];
if (poolObj is HyperPool<T> pool)
{
pool.Return(item, delaySeconds);
}
}
}
}
else
{
var type = typeof(T);
lock (_globalLock)
{
if (_pools.ContainsKey(type))
{
var poolObj = _pools[type];
if (poolObj is HyperPool<T> pool)
{
pool.Return(item, delaySeconds);
}
}
}
}
}
/// <summary>
/// 清理所有池
/// </summary>
public static void ClearAll()
{
lock (_globalLock)
{
foreach (var pool in _pools.Values)
{
if (pool is IDisposable disposable)
{
disposable.Dispose();
}
}
foreach (var pool in _namedPools.Values)
{
if (pool is IDisposable disposable)
{
disposable.Dispose();
}
}
_pools.Clear();
_namedPools.Clear();
}
if (_poolRoot != null)
{
if (Application.isPlaying)
{
UnityEngine.Object.Destroy(_poolRoot.gameObject);
}
else
{
UnityEngine.Object.DestroyImmediate(_poolRoot.gameObject);
}
_poolRoot = null;
}
}
/// <summary>
/// 获取所有池的统计信息
/// </summary>
public static string GetAllStats()
{
var sb = new System.Text.StringBuilder();
sb.AppendLine("=== Pool Manager Stats ===");
lock (_globalLock)
{
foreach (var kvp in _pools)
{
var pool = kvp.Value as HyperPool<object>;
if (pool != null)
{
sb.AppendLine(string.Format("{0}: {1}", kvp.Key.Name, pool.GetStats()));
}
}
foreach (var kvp in _namedPools)
{
var stats = GetStatsFromPool(kvp.Value);
if (!string.IsNullOrEmpty(stats))
{
sb.AppendLine(string.Format("{0}: {1}", kvp.Key, stats));
}
}
}
return sb.ToString();
}
private static Transform CreatePoolParent(string poolName)
{
var parent = new GameObject(string.Format("Pool_{0}", poolName)).transform;
parent.SetParent(PoolRoot);
return parent;
}
private static string GetStatsFromPool(object pool)
{
try
{
var method = pool.GetType().GetMethod("GetStats");
if (method != null)
{
return method.Invoke(pool, null) as string;
}
}
catch
{
// 忽略错误
}
return string.Empty;
}
}
#endregion
#region 使用示例
/// <summary>
/// 使用示例
/// </summary>
public static class ObjectPoolExamples
{
#region 示例1:基础引用类型(带构造函数)
// 带构造函数的类
public class EnemyData : IPoolable
{
private readonly int _id;
private readonly string _name;
// 带参数的构造函数
public EnemyData(int id, string name)
{
_id = id;
_name = name;
Health = 100;
}
// 无参构造函数(用于对象池)
public EnemyData() : this(0, "Unknown") { }
public int Health { get; set; }
public Vector3 Position { get; set; }
public Vector3 Velocity { get; set; }
public void OnPoolRent()
{
// 重置为默认值
Health = 100;
Position = Vector3.zero;
Velocity = Vector3.zero;
}
public void OnPoolReturn()
{
// 清理或重置
Health = 0;
}
}
public static void BasicExample()
{
// // 1. 使用自动创建的对象池
// var enemyPool = new HyperPool<EnemyData>();
// var enemy = enemyPool.Rent();
// // 使用enemy...
// enemyPool.Return(enemy);
//
// // 2. 延迟返回
// enemyPool.Return(enemy, 3.0f); // 3秒后返回
// 3. 使用自定义工厂的对象池(适用于没有无参构造函数的类)
var customPool = new HyperPool<EnemyData>(
factory: () => new EnemyData(1, "CustomEnemy"),
onRent: e => {
e.Health = 150; // 增强敌人
e.Position = Vector3.forward * 10;
},
onReturn: e => {
e.Health = 0;
Debug.Log(string.Format("Enemy returned with health: {0}", e.Health));
}
);
// 4. 使用PoolManager(带自定义工厂)
var managedPool = PoolManager.GetPool<EnemyData>(
factory: () => new EnemyData(2, "ManagedEnemy"),
onRent: e => e.Health = 200,
poolName: "CustomEnemies"
);
}
#endregion
#region 示例2:Unity Component对象池
public class Bullet : MonoBehaviour, IPoolable
{
public float Speed = 10f;
public float Lifetime = 3f;
public Vector3 Direction;
private float _timer;
public void OnPoolRent()
{
_timer = 0f;
gameObject.SetActive(true);
}
public void OnPoolReturn()
{
gameObject.SetActive(false);
Direction = Vector3.zero;
}
private void Update()
{
_timer += Time.deltaTime;
if (_timer >= Lifetime)
{
// 自动返回池中
PoolManager.Return(this, "Bullets");
return;
}
transform.position += Direction * Speed * Time.deltaTime;
}
}
public static void UnityComponentExample()
{
// 创建预制体(实际项目中应该从Resources或Addressables加载)
var bulletPrefab = new GameObject("BulletPrefab").AddComponent<Bullet>();
// 创建子弹池
var bulletPool = PoolManager.GetUnityPool(
bulletPrefab,
"Bullets",
initialCapacity: 20,
maxCapacity: 100,
onRent: bullet1 => {
bullet1.Direction = Vector3.forward;
bullet1.Speed = 15f;
},
onReturn: bullet1 => {
bullet1.transform.localPosition = Vector3.zero;
}
);
// 发射子弹
var bullet = bulletPool.Rent(
position: Vector3.zero,
rotation: Quaternion.identity
);
// 稍后回收
bulletPool.Return(bullet, 5f); // 5秒后回收
// 或者直接回收
bulletPool.Return(bullet);
}
#endregion
#region 示例3:没有无参构造函数的类
public class NetworkConnection : IPoolable
{
private readonly string _address;
private readonly int _port;
// 只有带参数的构造函数
public NetworkConnection(string address, int port)
{
_address = address;
_port = port;
}
public bool IsConnected { get; private set; }
public void Connect()
{
IsConnected = true;
}
public void Disconnect()
{
IsConnected = false;
}
public void OnPoolRent()
{
// 重置连接状态
IsConnected = false;
}
public void OnPoolReturn()
{
// 断开连接
Disconnect();
}
}
public static void NoParameterlessConstructorExample()
{
// 必须提供自定义工厂
var connectionPool = new HyperPool<NetworkConnection>(
factory: () => new NetworkConnection("127.0.0.1", 8080),
onRent: conn => {
conn.Connect();
Debug.Log("Connection rented and connected");
},
onReturn: conn => {
conn.Disconnect();
Debug.Log("Connection returned and disconnected");
}
);
// 使用连接池
connectionPool.Use(conn => {
// 使用连接
Debug.Log(string.Format("Using connection to {0}:{1}", "127.0.0.1", 8080));
});
}
#endregion
}
#endregion
}
类2:
cs
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Threading;
using UnityEngine;
namespace ILGame
{
#region 不依赖Span/Memory的自定义ArrayPool
/// <summary>
/// 自定义高性能ArrayPool(完全兼容所有Unity版本)
/// </summary>
public static class CustomArrayPool<T>
{
#region 配置
// 预定义的桶尺寸
private static readonly int[] BucketSizes =
{
16, 32, 64, 128, 256, 512, 1024, 2048, 4096,
8192, 16384, 32768, 65536, 131072, 262144
};
private const int MaxArraysPerBucket = 32;
private const int ThreadLocalCacheSize = 8;
#endregion
#region 核心数据结构
// 每个尺寸对应的桶
private static readonly Stack<T[]>[] Buckets;
// 线程本地缓存
[ThreadStatic]
private static ThreadLocalCache _threadLocalCache;
// 锁对象数组(减少锁竞争)
private static readonly object[] Locks;
// 统计信息
private static long TotalRentals;
private static long TotalReturns;
private static long CacheHits;
private static long NewAllocations;
private static long TotalMemoryAllocated;
#endregion
#region 初始化
static CustomArrayPool()
{
Buckets = new Stack<T[]>[BucketSizes.Length];
Locks = new object[BucketSizes.Length];
for (int i = 0; i < BucketSizes.Length; i++)
{
Buckets[i] = new Stack<T[]>(MaxArraysPerBucket);
Locks[i] = new object();
}
// 预热小尺寸桶
WarmupCommonSizes();
}
private static void WarmupCommonSizes()
{
// 预热常用尺寸
int[] warmupSizes = { 64, 256, 1024 };
foreach (var size in warmupSizes)
{
int bucketIndex = GetBucketIndex(size);
if (bucketIndex < Buckets.Length)
{
for (int i = 0; i < 4; i++)
{
var array = new T[BucketSizes[bucketIndex]];
lock (Locks[bucketIndex])
{
if (Buckets[bucketIndex].Count < MaxArraysPerBucket)
{
Buckets[bucketIndex].Push(array);
TotalMemoryAllocated += BucketSizes[bucketIndex] * EstimateElementSize();
}
}
}
}
}
}
#endregion
#region 公共API
/// <summary>
/// 租借数组
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static T[] Rent(int minimumLength)
{
if (minimumLength < 0)
throw new ArgumentOutOfRangeException(nameof(minimumLength));
if (minimumLength == 0)
return Array.Empty<T>();
// 1. 检查线程本地缓存
T[] array = GetFromThreadLocalCache(minimumLength);
if (array != null)
{
Interlocked.Increment(ref CacheHits);
Interlocked.Increment(ref TotalRentals);
return array;
}
// 2. 从桶中获取
int bucketIndex = GetBucketIndex(minimumLength);
if (bucketIndex < Buckets.Length)
{
array = GetFromBucket(bucketIndex);
if (array != null)
{
Interlocked.Increment(ref TotalRentals);
return array;
}
}
// 3. 创建新数组
Interlocked.Increment(ref NewAllocations);
Interlocked.Increment(ref TotalRentals);
int arraySize = bucketIndex < BucketSizes.Length
? BucketSizes[bucketIndex]
: CalculateOptimalSize(minimumLength);
return new T[arraySize];
}
/// <summary>
/// 返回数组
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Return(T[] array, bool clearArray = false)
{
if (array == null || array.Length == 0)
return;
Interlocked.Increment(ref TotalReturns);
// 清理数组
if (clearArray)
{
Array.Clear(array, 0, array.Length);
}
// 1. 尝试放入线程本地缓存
if (TryAddToThreadLocalCache(array))
return;
// 2. 放入桶中
int bucketIndex = GetBucketIndex(array.Length);
if (bucketIndex < Buckets.Length)
{
ReturnToBucket(array, bucketIndex);
}
}
/// <summary>
/// 预暖池
/// </summary>
public static void Prewarm(int countPerBucket = 4)
{
for (int i = 0; i < Buckets.Length; i++)
{
int size = BucketSizes[i];
lock (Locks[i])
{
int toAdd = Math.Min(countPerBucket, MaxArraysPerBucket - Buckets[i].Count);
for (int j = 0; j < toAdd; j++)
{
var array = new T[size];
Buckets[i].Push(array);
TotalMemoryAllocated += size * EstimateElementSize();
}
}
}
}
/// <summary>
/// 清理池
/// </summary>
public static void Clear()
{
for (int i = 0; i < Buckets.Length; i++)
{
lock (Locks[i])
{
Buckets[i].Clear();
}
}
if (_threadLocalCache != null)
{
_threadLocalCache.Clear();
}
TotalMemoryAllocated = 0;
}
/// <summary>
/// 获取统计信息
/// </summary>
public static string GetStats()
{
long totalCachedArrays = 0;
for (int i = 0; i < Buckets.Length; i++)
{
lock (Locks[i])
{
totalCachedArrays += Buckets[i].Count;
}
}
long threadLocalCount = _threadLocalCache?.Count ?? 0;
totalCachedArrays += threadLocalCount;
double hitRate = TotalRentals > 0
? (double)(TotalRentals - NewAllocations) / TotalRentals * 100
: 0;
return $"ArrayPool<{typeof(T).Name}>: " +
$"Rentals={TotalRentals}, " +
$"Returns={TotalReturns}, " +
$"CacheHits={CacheHits}, " +
$"NewAllocs={NewAllocations}, " +
$"HitRate={hitRate:F1}%, " +
$"CachedArrays={totalCachedArrays}, " +
$"Memory={TotalMemoryAllocated / 1024}KB";
}
#endregion
#region 私有辅助方法
private static T[] GetFromThreadLocalCache(int minimumLength)
{
if (_threadLocalCache == null)
return null;
return _threadLocalCache.Get(minimumLength);
}
private static bool TryAddToThreadLocalCache(T[] array)
{
if (_threadLocalCache == null)
_threadLocalCache = new ThreadLocalCache(ThreadLocalCacheSize);
return _threadLocalCache.TryAdd(array);
}
private static T[] GetFromBucket(int bucketIndex)
{
lock (Locks[bucketIndex])
{
if (Buckets[bucketIndex].Count > 0)
{
return Buckets[bucketIndex].Pop();
}
}
return null;
}
private static void ReturnToBucket(T[] array, int bucketIndex)
{
lock (Locks[bucketIndex])
{
if (Buckets[bucketIndex].Count < MaxArraysPerBucket)
{
Buckets[bucketIndex].Push(array);
}
}
}
private static int GetBucketIndex(int length)
{
for (int i = 0; i < BucketSizes.Length; i++)
{
if (length <= BucketSizes[i])
return i;
}
return BucketSizes.Length; // 超过最大桶尺寸
}
private static int CalculateOptimalSize(int minimumLength)
{
// 向上取整到最近的2的幂
int size = 16;
while (size < minimumLength && size < int.MaxValue / 2)
{
size <<= 1;
}
return Math.Min(size, 1024 * 1024); // 最大1MB
}
private static int EstimateElementSize()
{
if (typeof(T) == typeof(Vector3)) return 12;
if (typeof(T) == typeof(Vector2)) return 8;
if (typeof(T) == typeof(Color)) return 16;
if (typeof(T) == typeof(Matrix4x4)) return 64;
if (typeof(T) == typeof(float)) return 4;
if (typeof(T) == typeof(int)) return 4;
if (typeof(T) == typeof(double)) return 8;
return Marshal.SizeOf(typeof(T));
}
#endregion
#region 内部类
/// <summary>
/// 线程本地缓存
/// </summary>
private class ThreadLocalCache
{
private readonly T[][] Cache;
private readonly int[] Sizes;
public int Count;
public ThreadLocalCache(int capacity)
{
Cache = new T[capacity][];
Sizes = new int[capacity];
Count = 0;
}
public T[] Get(int minimumLength)
{
for (int i = 0; i < Count; i++)
{
if (Cache[i] != null && Sizes[i] >= minimumLength)
{
var array = Cache[i];
Cache[i] = null;
Sizes[i] = 0;
// 将找到的元素移到末尾,保持数组紧凑
if (i < Count - 1)
{
Cache[i] = Cache[Count - 1];
Sizes[i] = Sizes[Count - 1];
Cache[Count - 1] = null;
Sizes[Count - 1] = 0;
}
Count--;
return array;
}
}
return null;
}
public bool TryAdd(T[] array)
{
if (Count < Cache.Length)
{
Cache[Count] = array;
Sizes[Count] = array.Length;
Count++;
return true;
}
// 缓存已满,替换最小的数组
int smallestIndex = -1;
int smallestSize = int.MaxValue;
for (int i = 0; i < Count; i++)
{
if (Sizes[i] < smallestSize)
{
smallestSize = Sizes[i];
smallestIndex = i;
}
}
if (smallestIndex >= 0 && array.Length > smallestSize)
{
Cache[smallestIndex] = array;
Sizes[smallestIndex] = array.Length;
return true;
}
return false;
}
public void Clear()
{
for (int i = 0; i < Count; i++)
{
Cache[i] = null;
Sizes[i] = 0;
}
Count = 0;
}
}
#endregion
}
#endregion
#region Unity类型专用池
/// <summary>
/// Unity常用类型的专用数组池
/// </summary>
public static class UnityArrayPools
{
public static class Vector2Pool
{
public static Vector2[] Rent(int count) => CustomArrayPool<Vector2>.Rent(count);
public static void Return(Vector2[] array, bool clear = false) => CustomArrayPool<Vector2>.Return(array, clear);
public static string Stats => CustomArrayPool<Vector2>.GetStats();
}
public static class Vector3Pool
{
public static Vector3[] Rent(int count) => CustomArrayPool<Vector3>.Rent(count);
public static void Return(Vector3[] array, bool clear = false) => CustomArrayPool<Vector3>.Return(array, clear);
public static string Stats => CustomArrayPool<Vector3>.GetStats();
}
public static class Vector4Pool
{
public static Vector4[] Rent(int count) => CustomArrayPool<Vector4>.Rent(count);
public static void Return(Vector4[] array, bool clear = false) => CustomArrayPool<Vector4>.Return(array, clear);
public static string Stats => CustomArrayPool<Vector4>.GetStats();
}
public static class ColorPool
{
public static Color[] Rent(int count) => CustomArrayPool<Color>.Rent(count);
public static void Return(Color[] array, bool clear = false) => CustomArrayPool<Color>.Return(array, clear);
public static string Stats => CustomArrayPool<Color>.GetStats();
}
public static class Matrix4x4Pool
{
public static Matrix4x4[] Rent(int count) => CustomArrayPool<Matrix4x4>.Rent(count);
public static void Return(Matrix4x4[] array, bool clear = false) => CustomArrayPool<Matrix4x4>.Return(array, clear);
public static string Stats => CustomArrayPool<Matrix4x4>.GetStats();
}
public static class IntPool
{
public static int[] Rent(int count) => CustomArrayPool<int>.Rent(count);
public static void Return(int[] array, bool clear = false) => CustomArrayPool<int>.Return(array, clear);
public static string Stats => CustomArrayPool<int>.GetStats();
}
public static class FloatPool
{
public static float[] Rent(int count) => CustomArrayPool<float>.Rent(count);
public static void Return(float[] array, bool clear = false) => CustomArrayPool<float>.Return(array, clear);
public static string Stats => CustomArrayPool<float>.GetStats();
}
/// <summary>
/// 预暖所有Unity类型池
/// </summary>
public static void PrewarmAll(int countPerBucket = 4)
{
CustomArrayPool<Vector2>.Prewarm(countPerBucket);
CustomArrayPool<Vector3>.Prewarm(countPerBucket);
CustomArrayPool<Vector4>.Prewarm(countPerBucket);
CustomArrayPool<Color>.Prewarm(countPerBucket);
CustomArrayPool<Matrix4x4>.Prewarm(countPerBucket);
CustomArrayPool<int>.Prewarm(countPerBucket);
CustomArrayPool<float>.Prewarm(countPerBucket);
}
/// <summary>
/// 获取所有池的统计信息
/// </summary>
public static string GetAllStats()
{
return $"Vector2: {Vector2Pool.Stats}\n" +
$"Vector3: {Vector3Pool.Stats}\n" +
$"Vector4: {Vector4Pool.Stats}\n" +
$"Color: {ColorPool.Stats}\n" +
$"Matrix4x4: {Matrix4x4Pool.Stats}\n" +
$"Int: {IntPool.Stats}\n" +
$"Float: {FloatPool.Stats}";
}
}
#endregion
#region 智能池选择器(根据使用模式自动选择)
/// <summary>
/// 智能池管理器(自动选择最佳池策略)
/// </summary>
public static class SmartPoolManager
{
private static readonly Dictionary<Type, object> TypePools = new Dictionary<Type, object>();
private static readonly Dictionary<string, object> NamedPools = new Dictionary<string, object>();
private static readonly object GlobalLock = new object();
/// <summary>
/// 获取或创建智能池
/// </summary>
public static ISmartPool<T> GetSmartPool<T>(string name = null) where T : class, new()
{
if (name != null)
{
lock (GlobalLock)
{
if (NamedPools.TryGetValue(name, out var pool))
return (ISmartPool<T>)pool;
var newPool = CreateSmartPool<T>();
NamedPools[name] = newPool;
return newPool;
}
}
var type = typeof(T);
lock (GlobalLock)
{
if (TypePools.TryGetValue(type, out var pool))
return (ISmartPool<T>)pool;
var newPool = CreateSmartPool<T>();
TypePools[type] = newPool;
return newPool;
}
}
/// <summary>
/// 获取或创建数组智能池
/// </summary>
public static IArrayPool<T> GetArraySmartPool<T>(string name = null)
{
if (name != null)
{
lock (GlobalLock)
{
if (NamedPools.TryGetValue(name, out var pool))
return (IArrayPool<T>)pool;
var newPool = new SmartArrayPool<T>();
NamedPools[name] = newPool;
return newPool;
}
}
var type = typeof(T[]);
lock (GlobalLock)
{
if (TypePools.TryGetValue(type, out var pool))
return (IArrayPool<T>)pool;
var newPool = new SmartArrayPool<T>();
TypePools[type] = newPool;
return newPool;
}
}
/// <summary>
/// 清理所有池
/// </summary>
public static void ClearAll()
{
lock (GlobalLock)
{
foreach (var pool in TypePools.Values)
{
if (pool is IDisposable disposable)
disposable.Dispose();
}
foreach (var pool in NamedPools.Values)
{
if (pool is IDisposable disposable)
disposable.Dispose();
}
TypePools.Clear();
NamedPools.Clear();
}
}
private static ISmartPool<T> CreateSmartPool<T>() where T : class, new()
{
// 根据类型特性选择最佳池实现
if (typeof(T).IsValueType)
{
return new ValueTypeSmartPool<T>();
}
else if (typeof(T).GetConstructor(Type.EmptyTypes) != null)
{
return new ReferenceTypeSmartPool<T>();
}
else
{
return new FallbackSmartPool<T>();
}
}
}
/// <summary>
/// 智能池接口
/// </summary>
public interface ISmartPool<T> : IDisposable where T : class
{
T Rent();
void Return(T item);
void Prewarm(int count);
string GetStats();
}
/// <summary>
/// 数组池接口
/// </summary>
public interface IArrayPool<T> : IDisposable
{
T[] Rent(int minimumLength);
void Return(T[] array, bool clearArray = false);
void Prewarm(int countPerBucket);
string GetStats();
}
#endregion
#region 智能池实现
/// <summary>
/// 智能数组池(根据使用模式优化)
/// </summary>
public class SmartArrayPool<T> : IArrayPool<T>
{
// 小数组使用固定池
private readonly FixedSizeArrayPool<T> SmallPool;
// 大数组使用动态池
private readonly DynamicArrayPool<T> LargePool;
// 使用统计
private int SmallArrayRentals;
private int LargeArrayRentals;
private int SmallArrayReturns;
private int LargeArrayReturns;
// 阈值(根据使用模式动态调整)
private int SizeThreshold = 256;
public SmartArrayPool()
{
SmallPool = new FixedSizeArrayPool<T>();
LargePool = new DynamicArrayPool<T>();
}
public T[] Rent(int minimumLength)
{
if (minimumLength <= SizeThreshold)
{
Interlocked.Increment(ref SmallArrayRentals);
return SmallPool.Rent(minimumLength);
}
else
{
Interlocked.Increment(ref LargeArrayRentals);
return LargePool.Rent(minimumLength);
}
}
public void Return(T[] array, bool clearArray = false)
{
if (array == null) return;
if (array.Length <= SizeThreshold)
{
Interlocked.Increment(ref SmallArrayReturns);
SmallPool.Return(array, clearArray);
}
else
{
Interlocked.Increment(ref LargeArrayReturns);
LargePool.Return(array, clearArray);
}
// 动态调整阈值
AdjustThreshold();
}
public void Prewarm(int countPerBucket)
{
SmallPool.Prewarm(countPerBucket);
LargePool.Prewarm(countPerBucket);
}
public void Dispose()
{
SmallPool.Clear();
LargePool.Clear();
}
public string GetStats()
{
return $"SmartArrayPool<{typeof(T).Name}>: " +
$"SmallRentals={SmallArrayRentals}, LargeRentals={LargeArrayRentals}, " +
$"Threshold={SizeThreshold}, " +
$"SmallPool: {SmallPool.GetStats()}, " +
$"LargePool: {LargePool.GetStats()}";
}
private void AdjustThreshold()
{
// 根据使用频率动态调整阈值
int totalSmall = SmallArrayRentals + SmallArrayReturns;
int totalLarge = LargeArrayRentals + LargeArrayReturns;
if (totalSmall > totalLarge * 2)
{
// 小数组使用频繁,提高阈值
SizeThreshold = Math.Min(SizeThreshold * 2, 1024);
}
else if (totalLarge > totalSmall * 2)
{
// 大数组使用频繁,降低阈值
SizeThreshold = Math.Max(SizeThreshold / 2, 64);
}
}
}
/// <summary>
/// 固定尺寸数组池
/// </summary>
public class FixedSizeArrayPool<T>
{
private readonly Dictionary<int, Stack<T[]>> Pools;
private readonly object PoolLock = new object();
public FixedSizeArrayPool()
{
Pools = new Dictionary<int, Stack<T[]>>();
}
public T[] Rent(int minimumLength)
{
int size = RoundToNearestPowerOfTwo(minimumLength);
lock (PoolLock)
{
if (Pools.TryGetValue(size, out var pool) && pool.Count > 0)
{
return pool.Pop();
}
}
return new T[size];
}
public void Return(T[] array, bool clearArray)
{
if (array == null) return;
if (clearArray)
{
Array.Clear(array, 0, array.Length);
}
int size = array.Length;
lock (PoolLock)
{
if (!Pools.TryGetValue(size, out var pool))
{
pool = new Stack<T[]>();
Pools[size] = pool;
}
if (pool.Count < 16) // 限制缓存数量
{
pool.Push(array);
}
}
}
public void Prewarm(int countPerSize)
{
int[] commonSizes = { 16, 32, 64, 128, 256 };
lock (PoolLock)
{
foreach (var size in commonSizes)
{
if (!Pools.TryGetValue(size, out var pool))
{
pool = new Stack<T[]>();
Pools[size] = pool;
}
for (int i = 0; i < countPerSize && pool.Count < 16; i++)
{
pool.Push(new T[size]);
}
}
}
}
public void Clear()
{
lock (PoolLock)
{
Pools.Clear();
}
}
public string GetStats()
{
int totalArrays = 0;
int totalMemory = 0;
lock (PoolLock)
{
foreach (var kvp in Pools)
{
totalArrays += kvp.Value.Count;
totalMemory += kvp.Value.Count * kvp.Key * TypeSizeEstimator.EstimateElementSize<T>();
}
}
return $"Arrays={totalArrays}, Memory={totalMemory / 1024}KB";
}
private static int RoundToNearestPowerOfTwo(int value)
{
if (value <= 16) return 16;
if (value <= 32) return 32;
if (value <= 64) return 64;
if (value <= 128) return 128;
if (value <= 256) return 256;
if (value <= 512) return 512;
return 1024;
}
}
/// <summary>
/// 动态尺寸数组池
/// </summary>
public class DynamicArrayPool<T>
{
private readonly List<Stack<T[]>> Buckets;
private readonly int[] BucketSizes = { 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536 };
private readonly object[] Locks;
public DynamicArrayPool()
{
Buckets = new List<Stack<T[]>>(BucketSizes.Length);
Locks = new object[BucketSizes.Length];
for (int i = 0; i < BucketSizes.Length; i++)
{
Buckets.Add(new Stack<T[]>());
Locks[i] = new object();
}
}
public T[] Rent(int minimumLength)
{
int bucketIndex = GetBucketIndex(minimumLength);
lock (Locks[bucketIndex])
{
if (Buckets[bucketIndex].Count > 0)
{
return Buckets[bucketIndex].Pop();
}
}
return new T[BucketSizes[bucketIndex]];
}
public void Return(T[] array, bool clearArray)
{
if (array == null) return;
if (clearArray)
{
Array.Clear(array, 0, array.Length);
}
int bucketIndex = GetBucketIndex(array.Length);
lock (Locks[bucketIndex])
{
if (Buckets[bucketIndex].Count < 8) // 限制缓存数量
{
Buckets[bucketIndex].Push(array);
}
}
}
public void Prewarm(int countPerBucket)
{
for (int i = 0; i < Buckets.Count; i++)
{
lock (Locks[i])
{
for (int j = 0; j < countPerBucket && Buckets[i].Count < 8; j++)
{
Buckets[i].Push(new T[BucketSizes[i]]);
}
}
}
}
public void Clear()
{
for (int i = 0; i < Buckets.Count; i++)
{
lock (Locks[i])
{
Buckets[i].Clear();
}
}
}
public string GetStats()
{
int totalArrays = 0;
int totalMemory = 0;
for (int i = 0; i < Buckets.Count; i++)
{
lock (Locks[i])
{
totalArrays += Buckets[i].Count;
totalMemory += Buckets[i].Count * BucketSizes[i] * TypeSizeEstimator.EstimateElementSize<T>();
}
}
return $"Arrays={totalArrays}, Memory={totalMemory / 1024}KB";
}
private int GetBucketIndex(int length)
{
for (int i = 0; i < BucketSizes.Length; i++)
{
if (length <= BucketSizes[i])
return i;
}
return BucketSizes.Length - 1;
}
}
#endregion
#region 其他智能池实现
/// <summary>
/// 值类型智能池
/// </summary>
public class ValueTypeSmartPool<T> : ISmartPool<T> where T : class, new()
{
private readonly Stack<T> Pool = new Stack<T>(64);
private readonly object PoolLock = new object();
private int CreatedCount;
private int RentedCount;
private int ReturnedCount;
public T Rent()
{
Interlocked.Increment(ref RentedCount);
lock (PoolLock)
{
if (Pool.Count > 0)
{
return Pool.Pop();
}
}
Interlocked.Increment(ref CreatedCount);
return new T();
}
public void Return(T item)
{
if (item == null) return;
Interlocked.Increment(ref ReturnedCount);
// 对于值类型对象,重置状态
if (item is IResettable resettable)
{
resettable.Reset();
}
lock (PoolLock)
{
if (Pool.Count < 128) // 限制池大小
{
Pool.Push(item);
}
}
}
public void Prewarm(int count)
{
lock (PoolLock)
{
for (int i = 0; i < count && Pool.Count < 128; i++)
{
Pool.Push(new T());
Interlocked.Increment(ref CreatedCount);
}
}
}
public void Dispose()
{
lock (PoolLock)
{
Pool.Clear();
}
}
public string GetStats()
{
int poolSize;
lock (PoolLock)
{
poolSize = Pool.Count;
}
double hitRate = RentedCount > 0
? (double)(RentedCount - CreatedCount) / RentedCount * 100
: 0;
return $"ValueTypePool<{typeof(T).Name}>: " +
$"Created={CreatedCount}, Rented={RentedCount}, " +
$"Returned={ReturnedCount}, PoolSize={poolSize}, " +
$"HitRate={hitRate:F1}%";
}
}
/// <summary>
/// 引用类型智能池
/// </summary>
public class ReferenceTypeSmartPool<T> : ISmartPool<T> where T : class, new()
{
private readonly Stack<T> Pool = new Stack<T>(64);
private readonly object PoolLock = new object();
private int CreatedCount;
private int RentedCount;
private int ReturnedCount;
public T Rent()
{
Interlocked.Increment(ref RentedCount);
lock (PoolLock)
{
if (Pool.Count > 0)
{
return Pool.Pop();
}
}
Interlocked.Increment(ref CreatedCount);
return new T();
}
public void Return(T item)
{
if (item == null) return;
Interlocked.Increment(ref ReturnedCount);
lock (PoolLock)
{
if (Pool.Count < 64) // 限制池大小
{
Pool.Push(item);
}
}
}
public void Prewarm(int count)
{
lock (PoolLock)
{
for (int i = 0; i < count && Pool.Count < 64; i++)
{
Pool.Push(new T());
Interlocked.Increment(ref CreatedCount);
}
}
}
public void Dispose()
{
lock (PoolLock)
{
Pool.Clear();
}
}
public string GetStats()
{
int poolSize;
lock (PoolLock)
{
poolSize = Pool.Count;
}
double hitRate = RentedCount > 0
? (double)(RentedCount - CreatedCount) / RentedCount * 100
: 0;
return $"ReferenceTypePool<{typeof(T).Name}>: " +
$"Created={CreatedCount}, Rented={RentedCount}, " +
$"Returned={ReturnedCount}, PoolSize={poolSize}, " +
$"HitRate={hitRate:F1}%";
}
}
/// <summary>
/// 回退池(当其他池不适用时使用)
/// </summary>
public class FallbackSmartPool<T> : ISmartPool<T> where T : class
{
public T Rent()
{
return Activator.CreateInstance<T>();
}
public void Return(T item)
{
// 不缓存,直接丢弃
}
public void Prewarm(int count)
{
// 不做任何事情
}
public void Dispose()
{
// 不做任何事情
}
public string GetStats()
{
return $"FallbackPool<{typeof(T).Name}>: No pooling";
}
}
/// <summary>
/// 可重置接口
/// </summary>
public interface IResettable
{
void Reset();
}
#endregion
#region 实用工具
/// <summary>
/// 类型大小估计
/// </summary>
public static class TypeSizeEstimator
{
private static readonly Dictionary<Type, int> SizeCache = new Dictionary<Type, int>();
private static readonly object CacheLock = new object();
public static int EstimateElementSize<T>()
{
var type = typeof(T);
lock (CacheLock)
{
if (SizeCache.TryGetValue(type, out var size))
return size;
// Unity常用类型
if (type == typeof(Vector3)) size = 12;
else if (type == typeof(Vector2)) size = 8;
else if (type == typeof(Vector4)) size = 16;
else if (type == typeof(Quaternion)) size = 16;
else if (type == typeof(Color)) size = 16;
else if (type == typeof(Matrix4x4)) size = 64;
else if (type == typeof(Bounds)) size = 24;
else if (type == typeof(Ray)) size = 24;
else if (type == typeof(Plane)) size = 16;
else if (type == typeof(Ray2D)) size = 20;
// 基本类型
else if (type == typeof(bool)) size = 1;
else if (type == typeof(byte)) size = 1;
else if (type == typeof(sbyte)) size = 1;
else if (type == typeof(char)) size = 2;
else if (type == typeof(short)) size = 2;
else if (type == typeof(ushort)) size = 2;
else if (type == typeof(int)) size = 4;
else if (type == typeof(uint)) size = 4;
else if (type == typeof(float)) size = 4;
else if (type == typeof(long)) size = 8;
else if (type == typeof(ulong)) size = 8;
else if (type == typeof(double)) size = 8;
else if (type == typeof(decimal)) size = 16;
// 默认使用Marshal.SizeOf
else
{
try
{
size = Marshal.SizeOf(type);
}
catch
{
size = 8; // 保守估计
}
}
SizeCache[type] = size;
return size;
}
}
}
/// <summary>
/// 数组池扩展方法
/// </summary>
public static class ArrayPoolExtensions
{
/// <summary>
/// 安全使用数组(自动清理)
/// </summary>
public static TResult UseArray<T, TResult>(int length, Func<T[], TResult> action)
{
var array = CustomArrayPool<T>.Rent(length);
try
{
return action(array);
}
finally
{
CustomArrayPool<T>.Return(array);
}
}
/// <summary>
/// 安全使用数组(无返回值)
/// </summary>
public static void UseArray<T>(int length, Action<T[]> action)
{
var array = CustomArrayPool<T>.Rent(length);
try
{
action(array);
}
finally
{
CustomArrayPool<T>.Return(array);
}
}
/// <summary>
/// 批量租借数组
/// </summary>
public static T[][] RentBatch<T>(int count, int length)
{
var batch = new T[count][];
for (int i = 0; i < count; i++)
{
batch[i] = CustomArrayPool<T>.Rent(length);
}
return batch;
}
/// <summary>
/// 批量返回数组
/// </summary>
public static void ReturnBatch<T>(T[][] arrays, bool clearArrays = false)
{
if (arrays == null) return;
for (int i = 0; i < arrays.Length; i++)
{
CustomArrayPool<T>.Return(arrays[i], clearArrays);
}
}
}
#endregion
}