优化Object Pool 1.优化GC 2.优化每热路径 3.旧代码删除
This commit is contained in:
parent
13af026251
commit
1690ac7005
@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using AlicizaX;
|
||||
|
||||
namespace AlicizaX.ObjectPool
|
||||
@ -139,6 +140,8 @@ namespace AlicizaX.ObjectPool
|
||||
/// <returns>所有对象信息。</returns>
|
||||
public abstract ObjectInfo[] GetAllObjectInfos();
|
||||
|
||||
public abstract void GetAllObjectInfos(List<ObjectInfo> results);
|
||||
|
||||
internal abstract void Update(float elapseSeconds, float realElapseSeconds);
|
||||
|
||||
internal abstract void Shutdown();
|
||||
|
||||
@ -157,8 +157,8 @@ namespace AlicizaX.ObjectPool
|
||||
/// </summary>
|
||||
public void Unspawn()
|
||||
{
|
||||
m_Object.OnUnspawn();
|
||||
m_Object.LastUseTime = DateTime.UtcNow;
|
||||
m_Object.OnUnspawn();
|
||||
m_SpawnCount--;
|
||||
if (m_SpawnCount < 0)
|
||||
{
|
||||
|
||||
@ -14,10 +14,8 @@ namespace AlicizaX.ObjectPool
|
||||
{
|
||||
private readonly GameFrameworkMultiDictionary<string, Object<T>> m_Objects;
|
||||
private readonly Dictionary<object, Object<T>> m_ObjectMap;
|
||||
private readonly ReleaseObjectFilterCallback<T> m_DefaultReleaseObjectFilterCallback;
|
||||
private readonly List<Object<T>> m_CachedCanReleaseObjects;
|
||||
private readonly List<Object<T>> m_CachedToReleaseObjects;
|
||||
private readonly List<T> m_CachedCanReleaseTargets;
|
||||
private readonly IComparer<Object<T>> m_ReleaseObjectComparer;
|
||||
private readonly bool m_AllowMultiSpawn;
|
||||
private float m_AutoReleaseInterval;
|
||||
@ -40,10 +38,8 @@ namespace AlicizaX.ObjectPool
|
||||
{
|
||||
m_Objects = new GameFrameworkMultiDictionary<string, Object<T>>();
|
||||
m_ObjectMap = new Dictionary<object, Object<T>>();
|
||||
m_DefaultReleaseObjectFilterCallback = DefaultReleaseObjectFilterCallback;
|
||||
m_CachedCanReleaseObjects = new List<Object<T>>();
|
||||
m_CachedToReleaseObjects = new List<Object<T>>();
|
||||
m_CachedCanReleaseTargets = new List<T>();
|
||||
m_ReleaseObjectComparer = Comparer<Object<T>>.Create(ReleaseObjectComparer);
|
||||
m_AllowMultiSpawn = allowMultiSpawn;
|
||||
m_AutoReleaseInterval = autoReleaseInterval;
|
||||
@ -76,8 +72,14 @@ namespace AlicizaX.ObjectPool
|
||||
{
|
||||
get
|
||||
{
|
||||
GetCanReleaseObjects(m_CachedCanReleaseObjects);
|
||||
return m_CachedCanReleaseObjects.Count;
|
||||
int count = 0;
|
||||
foreach (KeyValuePair<object, Object<T>> kv in m_ObjectMap)
|
||||
{
|
||||
Object<T> obj = kv.Value;
|
||||
if (!obj.IsInUse && !obj.Locked && obj.CustomCanReleaseFlag)
|
||||
count++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
}
|
||||
|
||||
@ -405,7 +407,7 @@ namespace AlicizaX.ObjectPool
|
||||
/// </summary>
|
||||
public override void Release()
|
||||
{
|
||||
Release(Count - m_Capacity, m_DefaultReleaseObjectFilterCallback);
|
||||
ReleaseWithDefaultFilter(Count - m_Capacity);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -414,7 +416,7 @@ namespace AlicizaX.ObjectPool
|
||||
/// <param name="toReleaseCount">尝试释放对象数量。</param>
|
||||
public override void Release(int toReleaseCount)
|
||||
{
|
||||
Release(toReleaseCount, m_DefaultReleaseObjectFilterCallback);
|
||||
ReleaseWithDefaultFilter(toReleaseCount);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -434,11 +436,6 @@ namespace AlicizaX.ObjectPool
|
||||
public void Release(int toReleaseCount, ReleaseObjectFilterCallback<T> releaseObjectFilterCallback)
|
||||
{
|
||||
if (releaseObjectFilterCallback == null)
|
||||
{
|
||||
throw new GameFrameworkException("Release object filter callback is invalid.");
|
||||
}
|
||||
|
||||
if (releaseObjectFilterCallback == m_DefaultReleaseObjectFilterCallback)
|
||||
{
|
||||
ReleaseWithDefaultFilter(toReleaseCount);
|
||||
return;
|
||||
@ -457,13 +454,13 @@ namespace AlicizaX.ObjectPool
|
||||
|
||||
m_AutoReleaseTime = 0f;
|
||||
GetCanReleaseObjects(m_CachedCanReleaseObjects);
|
||||
m_CachedCanReleaseTargets.Clear();
|
||||
List<T> candidateTargets = new List<T>(m_CachedCanReleaseObjects.Count);
|
||||
foreach (Object<T> internalObject in m_CachedCanReleaseObjects)
|
||||
{
|
||||
m_CachedCanReleaseTargets.Add(internalObject.Peek());
|
||||
candidateTargets.Add(internalObject.Peek());
|
||||
}
|
||||
|
||||
List<T> toReleaseObjects = releaseObjectFilterCallback(m_CachedCanReleaseTargets, toReleaseCount, expireTime);
|
||||
List<T> toReleaseObjects = releaseObjectFilterCallback(candidateTargets, toReleaseCount, expireTime);
|
||||
if (toReleaseObjects == null || toReleaseObjects.Count <= 0)
|
||||
{
|
||||
return;
|
||||
@ -495,6 +492,18 @@ namespace AlicizaX.ObjectPool
|
||||
public override ObjectInfo[] GetAllObjectInfos()
|
||||
{
|
||||
List<ObjectInfo> results = new List<ObjectInfo>();
|
||||
GetAllObjectInfos(results);
|
||||
return results.ToArray();
|
||||
}
|
||||
|
||||
public override void GetAllObjectInfos(List<ObjectInfo> results)
|
||||
{
|
||||
if (results == null)
|
||||
{
|
||||
throw new GameFrameworkException("Results is invalid.");
|
||||
}
|
||||
|
||||
results.Clear();
|
||||
foreach (KeyValuePair<string, GameFrameworkLinkedListRange<Object<T>>> objectRanges in m_Objects)
|
||||
{
|
||||
foreach (Object<T> internalObject in objectRanges.Value)
|
||||
@ -502,8 +511,6 @@ namespace AlicizaX.ObjectPool
|
||||
results.Add(new ObjectInfo(internalObject.Name, internalObject.Locked, internalObject.CustomCanReleaseFlag, internalObject.Priority, internalObject.LastUseTime, internalObject.SpawnCount));
|
||||
}
|
||||
}
|
||||
|
||||
return results.ToArray();
|
||||
}
|
||||
|
||||
internal override void Update(float elapseSeconds, float realElapseSeconds)
|
||||
@ -529,7 +536,6 @@ namespace AlicizaX.ObjectPool
|
||||
m_ObjectMap.Clear();
|
||||
m_CachedCanReleaseObjects.Clear();
|
||||
m_CachedToReleaseObjects.Clear();
|
||||
m_CachedCanReleaseTargets.Clear();
|
||||
}
|
||||
|
||||
private Object<T> GetObject(object target)
|
||||
@ -566,10 +572,7 @@ namespace AlicizaX.ObjectPool
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!m_Objects.Remove(internalObject.Name, internalObject.NameNode))
|
||||
{
|
||||
m_Objects.Remove(internalObject.Name, internalObject);
|
||||
}
|
||||
m_Objects.Remove(internalObject.Name, internalObject.NameNode);
|
||||
|
||||
internalObject.NameNode = null;
|
||||
m_ObjectMap.Remove(targetObject.Target);
|
||||
@ -656,45 +659,6 @@ namespace AlicizaX.ObjectPool
|
||||
}
|
||||
}
|
||||
|
||||
private List<T> DefaultReleaseObjectFilterCallback(List<T> candidateObjects, int toReleaseCount, DateTime expireTime)
|
||||
{
|
||||
m_CachedCanReleaseTargets.Clear();
|
||||
|
||||
if (expireTime > DateTime.MinValue)
|
||||
{
|
||||
for (int i = candidateObjects.Count - 1; i >= 0; i--)
|
||||
{
|
||||
if (candidateObjects[i].LastUseTime <= expireTime)
|
||||
{
|
||||
m_CachedCanReleaseTargets.Add(candidateObjects[i]);
|
||||
candidateObjects.RemoveAt(i);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
toReleaseCount -= m_CachedCanReleaseTargets.Count;
|
||||
}
|
||||
|
||||
for (int i = 0; toReleaseCount > 0 && i < candidateObjects.Count; i++)
|
||||
{
|
||||
for (int j = i + 1; j < candidateObjects.Count; j++)
|
||||
{
|
||||
if (candidateObjects[i].Priority > candidateObjects[j].Priority
|
||||
|| candidateObjects[i].Priority == candidateObjects[j].Priority && candidateObjects[i].LastUseTime > candidateObjects[j].LastUseTime)
|
||||
{
|
||||
T temp = candidateObjects[i];
|
||||
candidateObjects[i] = candidateObjects[j];
|
||||
candidateObjects[j] = temp;
|
||||
}
|
||||
}
|
||||
|
||||
m_CachedCanReleaseTargets.Add(candidateObjects[i]);
|
||||
toReleaseCount--;
|
||||
}
|
||||
|
||||
return m_CachedCanReleaseTargets;
|
||||
}
|
||||
|
||||
private static int ReleaseObjectComparer(Object<T> a, Object<T> b)
|
||||
{
|
||||
int priorityCompare = a.Priority.CompareTo(b.Priority);
|
||||
|
||||
@ -16,6 +16,7 @@ namespace AlicizaX.ObjectPool
|
||||
private const int DefaultPriority = 0;
|
||||
|
||||
private readonly Dictionary<TypeNamePair, ObjectPoolBase> m_ObjectPools;
|
||||
private readonly List<ObjectPoolBase> m_ObjectPoolList;
|
||||
private readonly List<ObjectPoolBase> m_CachedAllObjectPools;
|
||||
private readonly Comparison<ObjectPoolBase> m_ObjectPoolComparer;
|
||||
|
||||
@ -25,6 +26,7 @@ namespace AlicizaX.ObjectPool
|
||||
public ObjectPoolService()
|
||||
{
|
||||
m_ObjectPools = new Dictionary<TypeNamePair, ObjectPoolBase>();
|
||||
m_ObjectPoolList = new List<ObjectPoolBase>();
|
||||
m_CachedAllObjectPools = new List<ObjectPoolBase>();
|
||||
m_ObjectPoolComparer = ObjectPoolComparer;
|
||||
}
|
||||
@ -50,9 +52,9 @@ namespace AlicizaX.ObjectPool
|
||||
/// <param name="realElapseSeconds">真实流逝时间,以秒为单位。</param>
|
||||
void IServiceTickable.Tick(float deltaTime)
|
||||
{
|
||||
foreach (KeyValuePair<TypeNamePair, ObjectPoolBase> objectPool in m_ObjectPools)
|
||||
for (int i = 0; i < m_ObjectPoolList.Count; i++)
|
||||
{
|
||||
objectPool.Value.Update(Time.deltaTime,Time.unscaledDeltaTime);
|
||||
m_ObjectPoolList[i].Update(deltaTime, Time.unscaledDeltaTime);
|
||||
}
|
||||
}
|
||||
|
||||
@ -63,12 +65,13 @@ namespace AlicizaX.ObjectPool
|
||||
|
||||
protected override void OnDestroyService()
|
||||
{
|
||||
foreach (KeyValuePair<TypeNamePair, ObjectPoolBase> objectPool in m_ObjectPools)
|
||||
for (int i = 0; i < m_ObjectPoolList.Count; i++)
|
||||
{
|
||||
objectPool.Value.Shutdown();
|
||||
m_ObjectPoolList[i].Shutdown();
|
||||
}
|
||||
|
||||
m_ObjectPools.Clear();
|
||||
m_ObjectPoolList.Clear();
|
||||
m_CachedAllObjectPools.Clear();
|
||||
}
|
||||
|
||||
@ -146,9 +149,9 @@ namespace AlicizaX.ObjectPool
|
||||
throw new GameFrameworkException("Condition is invalid.");
|
||||
}
|
||||
|
||||
foreach (KeyValuePair<TypeNamePair, ObjectPoolBase> objectPool in m_ObjectPools)
|
||||
for (int i = 0; i < m_ObjectPoolList.Count; i++)
|
||||
{
|
||||
if (condition(objectPool.Value))
|
||||
if (condition(m_ObjectPoolList[i]))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@ -231,11 +234,11 @@ namespace AlicizaX.ObjectPool
|
||||
throw new GameFrameworkException("Condition is invalid.");
|
||||
}
|
||||
|
||||
foreach (KeyValuePair<TypeNamePair, ObjectPoolBase> objectPool in m_ObjectPools)
|
||||
for (int i = 0; i < m_ObjectPoolList.Count; i++)
|
||||
{
|
||||
if (condition(objectPool.Value))
|
||||
if (condition(m_ObjectPoolList[i]))
|
||||
{
|
||||
return objectPool.Value;
|
||||
return m_ObjectPoolList[i];
|
||||
}
|
||||
}
|
||||
|
||||
@ -255,11 +258,11 @@ namespace AlicizaX.ObjectPool
|
||||
}
|
||||
|
||||
List<ObjectPoolBase> results = new List<ObjectPoolBase>();
|
||||
foreach (KeyValuePair<TypeNamePair, ObjectPoolBase> objectPool in m_ObjectPools)
|
||||
for (int i = 0; i < m_ObjectPoolList.Count; i++)
|
||||
{
|
||||
if (condition(objectPool.Value))
|
||||
if (condition(m_ObjectPoolList[i]))
|
||||
{
|
||||
results.Add(objectPool.Value);
|
||||
results.Add(m_ObjectPoolList[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -284,11 +287,11 @@ namespace AlicizaX.ObjectPool
|
||||
}
|
||||
|
||||
results.Clear();
|
||||
foreach (KeyValuePair<TypeNamePair, ObjectPoolBase> objectPool in m_ObjectPools)
|
||||
for (int i = 0; i < m_ObjectPoolList.Count; i++)
|
||||
{
|
||||
if (condition(objectPool.Value))
|
||||
if (condition(m_ObjectPoolList[i]))
|
||||
{
|
||||
results.Add(objectPool.Value);
|
||||
results.Add(m_ObjectPoolList[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -320,25 +323,13 @@ namespace AlicizaX.ObjectPool
|
||||
{
|
||||
if (sort)
|
||||
{
|
||||
List<ObjectPoolBase> results = new List<ObjectPoolBase>();
|
||||
foreach (KeyValuePair<TypeNamePair, ObjectPoolBase> objectPool in m_ObjectPools)
|
||||
{
|
||||
results.Add(objectPool.Value);
|
||||
}
|
||||
|
||||
List<ObjectPoolBase> results = new List<ObjectPoolBase>(m_ObjectPoolList);
|
||||
results.Sort(m_ObjectPoolComparer);
|
||||
return results.ToArray();
|
||||
}
|
||||
else
|
||||
{
|
||||
int index = 0;
|
||||
ObjectPoolBase[] results = new ObjectPoolBase[m_ObjectPools.Count];
|
||||
foreach (KeyValuePair<TypeNamePair, ObjectPoolBase> objectPool in m_ObjectPools)
|
||||
{
|
||||
results[index++] = objectPool.Value;
|
||||
}
|
||||
|
||||
return results;
|
||||
return m_ObjectPoolList.ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
@ -355,10 +346,7 @@ namespace AlicizaX.ObjectPool
|
||||
}
|
||||
|
||||
results.Clear();
|
||||
foreach (KeyValuePair<TypeNamePair, ObjectPoolBase> objectPool in m_ObjectPools)
|
||||
{
|
||||
results.Add(objectPool.Value);
|
||||
}
|
||||
results.AddRange(m_ObjectPoolList);
|
||||
|
||||
if (sort)
|
||||
{
|
||||
@ -1245,6 +1233,7 @@ namespace AlicizaX.ObjectPool
|
||||
|
||||
ObjectPool<T> objectPool = new ObjectPool<T>(name, allowMultiSpawn, autoReleaseInterval, capacity, expireTime, priority);
|
||||
m_ObjectPools.Add(typeNamePair, objectPool);
|
||||
m_ObjectPoolList.Add(objectPool);
|
||||
return objectPool;
|
||||
}
|
||||
|
||||
@ -1269,6 +1258,7 @@ namespace AlicizaX.ObjectPool
|
||||
Type objectPoolType = typeof(ObjectPool<>).MakeGenericType(objectType);
|
||||
ObjectPoolBase objectPool = (ObjectPoolBase)Activator.CreateInstance(objectPoolType, name, allowMultiSpawn, autoReleaseInterval, capacity, expireTime, priority);
|
||||
m_ObjectPools.Add(typeNamePair, objectPool);
|
||||
m_ObjectPoolList.Add(objectPool);
|
||||
return objectPool;
|
||||
}
|
||||
|
||||
@ -1278,6 +1268,7 @@ namespace AlicizaX.ObjectPool
|
||||
if (m_ObjectPools.TryGetValue(typeNamePair, out objectPool))
|
||||
{
|
||||
objectPool.Shutdown();
|
||||
m_ObjectPoolList.Remove(objectPool);
|
||||
return m_ObjectPools.Remove(typeNamePair);
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user