收录日期:2019/04/20 16:45:09 时间:2012-03-05 14:19:37 标签:c#,performance,arrays,diagnostics

As a diagnostic, I want to display the number of cycles per second in my app. (Think frames-per-second in a first-person-shooter.)

But I don't want to display the most recent value, or the average since launch. What I want to calculate is the mean of the last X values.

My question is, I suppose, about the best way to store these values. My first thought was to create a fixed size array, so each new value would push out the oldest. Is this the best way to do it? If so, how would I implement it?

EDIT: Here's the class I wrote: RRQueue. It inherits Queue, but enforces the capacity and dequeues if necessary.

EDIT 2: Pastebin is so passé. Now on a GitHub repo.

The easiest option for this is probably to use a Queue<T>, as this provides the first-in, first-out behavior you're after. Just Enqueue() your items, and when you have more than X items, Dequeue() the extra item(s).

A simple but fast implementation:

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

You should take a look at the performance monitoring built into Windows :D.

MSDN

The API will feel a bit wonky if you haven't played with it before, but it's fast, powerful, extensible, and it makes quick work of getting usable results.

Possibly use a filter:

average = 0.9*average + 0.1*value where 'value' is the most recent measurement

Vary with the 0.9 and 0.1 (as long as the sum of these two is 1)

This is not exactly an average, but it does filter out spikes, transients, etc, but does not require arrays for storage.

Greetings, Karel

If you need the fastest implementation, then yes, a fixed-size array ()with a separate count would be fastest.