繁体   English   中英

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

[英]Simple round robin (moving average) array in C#

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

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

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

编辑:这是我写的类: RRQueue 它继承 Queue,但在必要时强制执行容量和出队。

编辑 2: Pastebin 太过时了。 现在在GitHub 存储库上

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

一个简单但快速的实现:

// 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;
}

可能使用过滤器:

平均值 = 0.9*平均值 + 0.1*值,其中“值”是最近的测量值

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

这并不完全是平均值,但它确实过滤掉了尖峰、瞬变等,但不需要阵列进行存储。

你好,卡雷尔

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

您应该看看内置于 Windows 中的性能监控:D。

MSDN

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

我的实现:

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);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM