C#中的简单循环(移动平均)数组

时间:2010-06-22 20:34:23

标签: c# performance arrays diagnostics

作为诊断,我想在我的应用中显示每秒的周期数。 (想想第一人称射击游戏中的每秒帧数。)

但我不想显示最近的值,或者自发布以来的平均值。我想要计算的是最后X值的平均值。

我想,我的问题是关于存储这些值的最佳方法。我的第一个想法是创建一个固定大小的数组,因此每个新值都会推出最老的数组。这是最好的方法吗?如果是这样,我将如何实现它?

修改 这是我写的课程:RRQueue。它继承了Queue,但强制执行容量并在必要时出列。

编辑2: Pastebin太过分了。现在a GitHub repo

6 个答案:

答案 0 :(得分:16)

最简单的选择可能是使用Queue<T>,因为它提供了您所追求的先进先出行为。只需Enqueue()您的商品,当您拥有超过X件商品时,Dequeue()额外商品。

答案 1 :(得分:13)

简单但快速的实施:

// untested

int[] values = new int [10];  // all 0's initially
int sum = 0;
int pos = 0;

void AddValue (int v)
{
   sum -= values[pos];  // only need the array to subtract old value
   sum += v;
   values[pos] = v;     
   pos = (pos + 1) % values.length;    
}

int Average()
{
   return sum / values.length;
}

答案 2 :(得分:1)

如果您需要最快的实现,那么是,具有单独计数的固定大小的数组()将是最快的。

答案 3 :(得分:1)

可能使用过滤器:

平均值= 0.9 *平均值+ 0.1 *值 其中“价值”是最近的衡量标准

随着0.9和0.1的变化(只要这两者之和为1)

这不是一般的平均值,但它会过滤掉尖峰,瞬变等,但不需要存储阵列。

问候, 卡雷尔

答案 4 :(得分:0)

您应该看一下Windows内置的性能监控:D。

MSDN

如果您以前没有使用它,API会感觉有点不稳定,但它快速,强大,可扩展,并且可以快速获得可用的结果。

答案 5 :(得分:0)

我的实施:

class RoundRobinAverage
{
    int[] buffer;
    byte _size;
    byte _idx = 0;
    public RoundRobinAverage(byte size)
    {
        _size = size;
        buffer = new int[size];
    }

    public double Calc(int probeValue)
    {
        buffer[_idx++] = probeValue;
        if (_idx >= _size)
            _idx = 0;

        return buffer.Sum() / _size;
    }
}

用法:

private RoundRobinAverage avg = new RoundRobinAverage(10);\
...
var average = avg.Calc(123);