diff a/src/hotspot/share/utilities/numberSeq.cpp b/src/hotspot/share/utilities/numberSeq.cpp --- a/src/hotspot/share/utilities/numberSeq.cpp +++ b/src/hotspot/share/utilities/numberSeq.cpp @@ -39,13 +39,21 @@ _davg = val; // and the variance is 0 _dvariance = 0.0; } else { // otherwise, calculate both - _davg = (1.0 - _alpha) * val + _alpha * _davg; + // Formula from "Incremental calculation of weighted mean and variance" by Tony Finch + // diff := x - mean + // incr := alpha * diff + // mean := mean + incr + // variance := (1 - alpha) * (variance + diff * incr) + // PDF available at https://fanf2.user.srcf.net/hermes/doc/antiforgery/stats.pdf + // Note: alpha is actually (1.0 - _alpha) in our code double diff = val - _davg; - _dvariance = (1.0 - _alpha) * diff * diff + _alpha * _dvariance; + double incr = (1.0 - _alpha) * diff; + _davg += incr; + _dvariance = _alpha * (_dvariance + diff * incr); } } double AbsSeq::avg() const { if (_num == 0)