From 0ed1ce200eeaa853438694bfdbd5041e063bc154 Mon Sep 17 00:00:00 2001 From: Gahow Wang Date: Sat, 23 May 2026 21:00:24 +0800 Subject: [PATCH] metrics: replace round-based percentile with linear interpolation (B5) The previous implementation used round((n-1) * pct), which under Python's banker's rounding returned the upper-middle element on every even-length array (e.g. p50 of [1,2,3,4] returned 3 instead of 2.5). All summary JSONs were biased upward at p50 as a result. Match numpy.percentile's default linear interpolation between the two adjacent sorted values. --- replayer/metrics.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/replayer/metrics.py b/replayer/metrics.py index f48cbf2..aaf9f90 100644 --- a/replayer/metrics.py +++ b/replayer/metrics.py @@ -101,7 +101,11 @@ def _stats(values: list[float | None]) -> dict[str, float] | None: def _percentile(sorted_vals: list[float], pct: float) -> float: - if len(sorted_vals) == 1: + n = len(sorted_vals) + if n == 1: return sorted_vals[0] - idx = round((len(sorted_vals) - 1) * pct) - return sorted_vals[idx] + rank = pct * (n - 1) + lo = int(rank) + hi = min(lo + 1, n - 1) + frac = rank - lo + return sorted_vals[lo] * (1 - frac) + sorted_vals[hi] * frac