116 lines
3.8 KiB
C#
116 lines
3.8 KiB
C#
using System.Collections.Concurrent;
|
|
using UnityEngine;
|
|
|
|
namespace UVC.Data.Core
|
|
{
|
|
/// <summary>
|
|
/// DataArray 객체의 재사용을 위한 풀링 클래스입니다.
|
|
/// </summary>
|
|
public static class DataArrayPool
|
|
{
|
|
private static readonly ConcurrentQueue<DataArray> _pool = new ConcurrentQueue<DataArray>();
|
|
private static int _maxPoolSize = 100; // DataArray는 DataObject보다 수가 적을 것이므로 기본값 조정
|
|
|
|
// --- 통계용 필드 ---
|
|
private static int _inUseCount = 0;
|
|
private static int _peakUsage = 0;
|
|
private static int _poolMisses = 0;
|
|
private static readonly object _statsLock = new object();
|
|
|
|
static DataArrayPool()
|
|
{
|
|
// maxPoolSize만큼의 DataObject 인스턴스를 미리 생성하여 풀에 추가합니다.
|
|
for (int i = 0; i < _maxPoolSize; i++)
|
|
{
|
|
_pool.Enqueue(new DataArray() { IsInPool = true, CreatedFromPool = true });
|
|
}
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// 풀에서 DataArray 객체를 가져옵니다. 풀이 비어있으면 새로 생성합니다.
|
|
/// </summary>
|
|
/// <returns>재사용 가능한 DataArray 객체</returns>
|
|
public static DataArray Get()
|
|
{
|
|
bool fromPool = _pool.TryDequeue(out var array);
|
|
|
|
lock (_statsLock)
|
|
{
|
|
_inUseCount++;
|
|
if (_inUseCount > _peakUsage)
|
|
{
|
|
_peakUsage = _inUseCount;
|
|
}
|
|
|
|
if (!fromPool)
|
|
{
|
|
_poolMisses++;
|
|
if (_inUseCount > _maxPoolSize)
|
|
{
|
|
int oldSize = _maxPoolSize;
|
|
_maxPoolSize += 100; // 증가량 조정
|
|
//Debug.Log($"DataArrayPool size automatically increased from {oldSize} to {_maxPoolSize}. Peak usage: {_peakUsage}");
|
|
}
|
|
}
|
|
}
|
|
|
|
//if(_peakUsage % 10 == 0) Debug.Log($"DataArrayPool stats: {GetStats()}");
|
|
|
|
if (fromPool)
|
|
{
|
|
array.IsInPool = false;
|
|
}
|
|
return fromPool ? array : new DataArray() { CreatedFromPool = true };
|
|
}
|
|
|
|
/// <summary>
|
|
/// 사용이 끝난 DataArray 객체를 풀에 반환합니다.
|
|
/// </summary>
|
|
/// <param name="array">반환할 DataArray 객체</param>
|
|
public static void Return(DataArray array)
|
|
{
|
|
if (array == null || array.IsInPool) return;
|
|
|
|
bool shouldReturnToPool;
|
|
|
|
lock (_statsLock)
|
|
{
|
|
_inUseCount--;
|
|
shouldReturnToPool = _pool.Count < _maxPoolSize;
|
|
}
|
|
|
|
if (shouldReturnToPool)
|
|
{
|
|
array.Reset();
|
|
array.IsInPool = true;
|
|
_pool.Enqueue(array);
|
|
}
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// 풀의 현재 성능 통계를 문자열로 반환합니다.
|
|
/// </summary>
|
|
/// <returns>풀 통계 (최대 사용량, 현재 사용량, 풀 비어있을 때 생성 횟수, 현재 풀 크기)</returns>
|
|
public static string GetStats()
|
|
{
|
|
lock (_statsLock)
|
|
{
|
|
return $"최대 사용량: {_peakUsage}, 현재 사용량: {_inUseCount}, 풀 비어있을 때 생성 횟수: {_poolMisses}, 현재 풀 크기: {_pool.Count}, Max Size: {_maxPoolSize}";
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 풀 통계를 초기화합니다.
|
|
/// </summary>
|
|
public static void ResetStats()
|
|
{
|
|
lock (_statsLock)
|
|
{
|
|
_peakUsage = 0;
|
|
_poolMisses = 0;
|
|
}
|
|
}
|
|
}
|
|
} |