go-metrics icon indicating copy to clipboard operation
go-metrics copied to clipboard

Replace our EWMA with VividCortex/ewma

Open rcrowley opened this issue 12 years ago • 1 comments

https://github.com/VividCortex/ewma looks simpler than ours.

rcrowley avatar Sep 14 '13 18:09 rcrowley

https://github.com/VividCortex/ewma

@rcrowley @mihasya The package calculates an EWMA that is time-independent, meaning that old data points decay with each incoming metric (instead of decaying over time). If this approach were to be used, then calling NewEMWA1(), NewEMWA15(), etc. would not accurately reflect a time-sensitive EWMA.

An alternative solution is to add a timestamp field to StandardEWMA. This way, the EWMA can be calculated on demand (i.e any time Rate() is called), as opposed to concurrently, using the following formula:

[ (1 - alpha) ^ periods ] * oldRate

Where periods are the number of seconds (or any other time interval) that have passed since the last update. Here is an example in Go:

func (a *StandardEWMA) Rate() float64 {
	if atomic.LoadUint32(&a.init) == 0 {
		return 0
	}

	// Calculate periods since last update.
	lastTime := atomic.LoadInt64(&a.time)
	currentTime := time.Now().UTC().UnixNano()

        // 5-second periods. This is equivalent to Tick()-ing every 5 seconds.
	periods := math.Floor(float64(currentTime-lastTime) / float64(5e9))

	// Calculate new rate based on time since last update.
	// [(1-alpha)^periods] * lastRate
	lastRate := math.Float64frombits(atomic.LoadUint64(&a.rate))
	currentRate := math.Pow(1-a.alpha, periods) * lastRate

	return currentRate * 1e9
}

Where a.time is the Unix timestamp of when the StandardEMWA was updated last.

This would also fix Issue #283

Let me know if you agree with my approach and whether you'd like for me to open a PR.

zeim839 avatar Aug 03 '23 11:08 zeim839