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.Reflection.Emit;
using DotRecast.Core;
using DotRecast.Core.Buffers;
using DotRecast.Core.Numerics;
namespace DotRecast.Detour.Crowd
@ -34,7 +35,7 @@ namespace DotRecast.Detour.Crowd
private float _maxTimeToFindPath;
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()
{
@ -87,17 +88,23 @@ namespace DotRecast.Detour.Crowd
long duration = RcFrequency.Ticks - _executionTimings[name];
if (!_executionTimingSamples.TryGetValue(name, out var s))
{
s = new List<long>();
s = new RcCyclicBuffer<long>(TIMING_SAMPLES);
_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);
_executionTimings[name] = (long)s.Average();
return sum / buffer.Length;
}
}
}