How to calculate simple moving average faster in C#?
public class MovingAverage
{
private Queue<Decimal> samples = new Queue<Decimal>();
private int windowSize = 16;
private Decimal sampleAccumulator;
public Decimal Average { get; private set; }
/// <summary>
/// Computes a new windowed average each time a new sample arrives
/// </summary>
/// <param name="newSample"></param>
public void ComputeAverage(Decimal newSample)
{
sampleAccumulator += newSample;
samples.Enqueue(newSample);
if (samples.Count > windowSize)
{
sampleAccumulator -= samples.Dequeue();
}
Average = sampleAccumulator / samples.Count;
}
}
Your main problem is that you throw away too much information for each iteration. If you want to run this fast, you need to keep a buffer of the same size as the frame length.
This code will run moving averages for your whole dataset:
(Not real C# but you should get the idea)
decimal buffer[] = new decimal[period];
decimal output[] = new decimal[data.Length];
current_index = 0;
for (int i=0; i<data.Length; i++)
{
buffer[current_index] = data[i]/period;
decimal ma = 0.0;
for (int j=0;j<period;j++)
{
ma += buffer[j];
}
output[i] = ma;
current_index = (current_index + 1) % period;
}
return output;
Please note that it may be tempting to keep a running cumsum instead of keeping the whole buffer and calculating the value for each iteration, but this does not work for very long data lengths as your cumulative sum will grow so big that adding small additional values will result in rounding errors.