fix: calcAverageFrameTime Remove one maximum (#7382)

Co-authored-by: lingkong <gaokun333@qq.com>
Co-authored-by: 白熱 <sonne@asaki.me>
This commit is contained in:
lingkong333
2026-08-01 12:40:09 +08:00
committed by GitHub
co-authored by lingkong 白熱
parent f23c9ee81e
commit 343faadedf
2 changed files with 22 additions and 5 deletions
@@ -97,4 +97,15 @@ describe('performance monitor', () => {
expect(average.averageFrameTime).toBeCloseTo(16.67, 2);
expect(average.variance).toBe(0);
});
it('removes only one minimum and maximum from duplicate samples', () => {
const average = new RollingAverage(3);
for (const frameTime of [10, 10, 20]) {
average.addFrameTime(frameTime);
average.calcAverageFrameTime();
}
expect(average.averageFrameTime).toBe(10);
});
});
@@ -265,11 +265,17 @@ export class RollingAverage {
this._sampleCount++;
}
// Remove one maximum and one minimum to ensure the accuracy of the average value.
const min = Math.min(...this._samples);
const max = Math.min(...this._samples);
const filteredData = this._samples.filter((v) => v !== max && v !== min);
this.averageFrameTime = filteredData.reduce((sum, value) => sum + value, 0) / filteredData.length;
// Once the window is full, exclude one minimum and maximum to reduce outlier bias.
const shouldTrimExtremes = this.isSaturated() && this._sampleCount > 2;
const sampleSum = this._samples.reduce((sum, value) => sum + value, 0);
if (shouldTrimExtremes) {
const min = Math.min(...this._samples);
const max = Math.max(...this._samples);
this.averageFrameTime = (sampleSum - min - max) / (this._sampleCount - 2);
} else {
this.averageFrameTime = sampleSum / this._sampleCount;
}
// add new value to mean
delta = frameDuration - this.averageFrameTime;