Replaced list with cyclic buffer

This commit is contained in:
wreng 2024-02-16 20:13:10 +03:00 committed by Ikpil
parent 653a9e794b
commit a359686171
2 changed files with 61 additions and 6 deletions

View File

@ -0,0 +1,48 @@
using System;
namespace DotRecast.Core.Buffers
{
public class RcCyclicBuffer<T>
{
public int MinIndex { get; private set; }
public int MaxIndex { get; private set; }
public int Count => MaxIndex - MinIndex + 1;
public readonly int Size;
public T this[int index] => Get(index);
private readonly T[] _buffer;
public RcCyclicBuffer(in int size)
{
_buffer = new T[size];
Size = size;
MinIndex = 0;
MaxIndex = -1;
}
public void Add(in T item)
{
MaxIndex++;
var index = MaxIndex % Size;
if (MaxIndex >= Size)
MinIndex = MaxIndex - Size + 1;
_buffer[index] = item;
}
public T Get(in int index)
{
if (index < MinIndex || index > MaxIndex)
throw new ArgumentOutOfRangeException();
return _buffer[index % Size];
}
public Span<T> AsSpan()
{
return _buffer.AsSpan(0, Count);
}
}
}

View File

@ -23,6 +23,7 @@ using System.Diagnostics;
using System.Linq; using System.Linq;
using System.Reflection.Emit; using System.Reflection.Emit;
using DotRecast.Core; using DotRecast.Core;
using DotRecast.Core.Buffers;
using DotRecast.Core.Numerics; using DotRecast.Core.Numerics;
namespace DotRecast.Detour.Crowd namespace DotRecast.Detour.Crowd
@ -34,7 +35,7 @@ namespace DotRecast.Detour.Crowd
private float _maxTimeToFindPath; private float _maxTimeToFindPath;
private readonly Dictionary<DtCrowdTimerLabel, long> _executionTimings = new Dictionary<DtCrowdTimerLabel, long>(); private readonly Dictionary<DtCrowdTimerLabel, long> _executionTimings = new Dictionary<DtCrowdTimerLabel, long>();
private readonly Dictionary<DtCrowdTimerLabel, List<long>> _executionTimingSamples = new Dictionary<DtCrowdTimerLabel, List<long>>(); private readonly Dictionary<DtCrowdTimerLabel, RcCyclicBuffer<long>> _executionTimingSamples = new Dictionary<DtCrowdTimerLabel, RcCyclicBuffer<long>>();
public float MaxTimeToEnqueueRequest() public float MaxTimeToEnqueueRequest()
{ {
@ -87,17 +88,23 @@ namespace DotRecast.Detour.Crowd
long duration = RcFrequency.Ticks - _executionTimings[name]; long duration = RcFrequency.Ticks - _executionTimings[name];
if (!_executionTimingSamples.TryGetValue(name, out var s)) if (!_executionTimingSamples.TryGetValue(name, out var s))
{ {
s = new List<long>(); s = new RcCyclicBuffer<long>(TIMING_SAMPLES);
_executionTimingSamples.Add(name, s); _executionTimingSamples.Add(name, s);
} }
if (s.Count == TIMING_SAMPLES) s.Add(duration);
_executionTimings[name] = CalculateAverage(s.AsSpan());
}
private static long CalculateAverage(Span<long> buffer)
{
long sum = 0L;
foreach (var item in buffer)
{ {
s.RemoveAt(0); sum += item;
} }
s.Add(duration); return sum / buffer.Length;
_executionTimings[name] = (long)s.Average();
} }
} }
} }