I am using DescriptiveStatistics to track the moving average of some metrics. I have a thread that submits the metric value every minute, and I track the 10 minute moving average of the metric by using the setWindowSize(10)
method on DescriptiveStatistics.
This works fine for tracking a single moving average but I actually need to track multiple moving averages, i.e. the 1 minute average, the 5 minute average, and the 10 minute average.
Currently I have the following options:
Have 3 different DescriptiveStatistics instances with 3 different windows. However, this means we store the raw metrics multiple times which is not ideal.
Have 1 instance of DescriptiveStatistics and do something like the following when querying for a moving average:
int minutes = <set from parameter>; DescriptiveStatistics stats = <class variable>; if (minutes == stats.getN()) return stats.getMean(); SummaryStatistics subsetStats = new SummaryStatistics(); for (int i = 0; i < minutes; i++) { subsetStats.addValue(stats.getElement((int)stats.getN() - i - 1)); } return subsetStats.getMean();
However, option 2 means that I have to re-compute a bunch of averages every time I query for a moving average whose window is smaller than the DescriptiveStats window size.
Is there a way to do this better? I want to store 1 copy of the metrics data and continually calculate N moving averages of it with different intervals. This might be getting into the land of Codahale Metrics or Netflix Servo, but I don't want to have to use a heavyweight library just for this.