JYe*_*ton 16 c# collections circular-buffer
我想对特定方法进行一些性能测量,但我想平均完成所需的时间.(这是一个C#Winforms应用程序,但这个问题很适用于其他框架.)
我有一个秒表,我在方法开始时重置并在结束时停止.我想将最后10个值存储在列表或数组中.每个新增加的值都应该从列表中删除最旧的值.
我会定期调用另一种方法来平均所有存储的值.
我认为这个构造是一个循环缓冲区是正确的吗?
如何创建具有最佳性能的缓冲区?现在我有以下内容:
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);
}
Run Code Online (Sandbox Code Playgroud)
这在某种程度上似乎效率低下,但也许并非如此.
建议?
Tho*_*que 19
您可以创建自定义集合:
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();
}
}
Run Code Online (Sandbox Code Playgroud)
您当前的解决方案有效,但效率低,因为删除第一项List<T>是昂贵的.
private int ct = 0;
private long[] times = new long[10];
void DoStuff ()
{
...
times[ct] = MyStopWatch.ElapsedMilliseconds;
ct = (ct + 1) % times.Length; // Wrap back around to 0 when we reach the end.
}
Run Code Online (Sandbox Code Playgroud)
这是一个简单的圆形结构.这不需要其他解决方案具有的链表节点的数组复制或垃圾收集.