I want to do some performance measuring of a particular method, but I'd like to average the time it takes to complete. (This is a C# Winforms application, but this question could well apply to other frameworks.)
I have a Stopwatch which I reset at the start of the method and stop at the end. I'd like to store the last 10 values in a list or array. Each new value added should push the oldest value off the list.
Periodically I will call another method which will average all stored values.
Am I correct in thinking that this construct is a circular buffer?
How can I create such a buffer with optimal performance? Right now I have the following:
List<long> PerfTimes = new List<long>(10);
// ...
private void DoStuff()
{
MyStopWatch.Restart();
// ...
MyStopWatch.Stop();
PerfTimes.Add(MyStopWatch.ElapsedMilliseconds);
if (PerfTimes.Count > 10) PerfTimes.RemoveAt(0);
}
This seems inefficient somehow, but perhaps it's not.
Suggestions?
You could create a custom collection:
class SlidingBuffer<T> : IEnumerable<T>
{
private readonly Queue<T> _queue;
private readonly int _maxCount;
public SlidingBuffer(int maxCount)
{
_maxCount = maxCount;
_queue = new Queue<T>(maxCount);
}
public void Add(T item)
{
if (_queue.Count == _maxCount)
_queue.Dequeue();
_queue.Enqueue(item);
}
public IEnumerator<T> GetEnumerator()
{
return _queue.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
Your current solution works, but it's inefficient, because removing the first item of a List<T>
is expensive.