Skip to content

Commit a9b871f

Browse files
committed
fix(bench): correct percentile calculation using nearest-rank method
Fixed incorrect percentile index calculation in calculate_statistics(): Previous (incorrect): - p50_idx = (n * 0.50) as usize - For 100 samples: idx=50 → accesses 51st value (should be 50th) - Used .min(len-1) as a band-aid to prevent out-of-bounds Current (correct, nearest-rank): - p50_idx = ceil(n * 0.50) - 1 - For 100 samples: ceil(50.0) - 1 = 49 → accesses 50th value ✓ - Uses saturating_sub(1) to handle edge cases The nearest-rank method is standard for benchmark percentile calculations and ensures we access the correct element in the sorted array. Examples: - n=100, p50: ceil(50.0)-1 = 49 (50th percentile) - n=100, p95: ceil(95.0)-1 = 94 (95th percentile) - n=100, p99: ceil(99.0)-1 = 98 (99th percentile)
1 parent 7117001 commit a9b871f

File tree

1 file changed

+9
-7
lines changed

1 file changed

+9
-7
lines changed

src/bin/bench_throughput.rs

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -96,13 +96,15 @@ impl BenchmarkResult {
9696
let min = sorted_times[0];
9797
let max = sorted_times[sorted_times.len() - 1];
9898

99-
let p50_idx = (sorted_times.len() as f64 * 0.50) as usize;
100-
let p95_idx = (sorted_times.len() as f64 * 0.95) as usize;
101-
let p99_idx = (sorted_times.len() as f64 * 0.99) as usize;
102-
103-
let p50 = sorted_times[p50_idx.min(sorted_times.len() - 1)];
104-
let p95 = sorted_times[p95_idx.min(sorted_times.len() - 1)];
105-
let p99 = sorted_times[p99_idx.min(sorted_times.len() - 1)];
99+
// Nearest-rank percentile calculation: ceil(p * n) - 1
100+
let n = sorted_times.len() as f64;
101+
let p50_idx = ((n * 0.50).ceil() as usize).saturating_sub(1);
102+
let p95_idx = ((n * 0.95).ceil() as usize).saturating_sub(1);
103+
let p99_idx = ((n * 0.99).ceil() as usize).saturating_sub(1);
104+
105+
let p50 = sorted_times[p50_idx];
106+
let p95 = sorted_times[p95_idx];
107+
let p99 = sorted_times[p99_idx];
106108

107109
// Calculate standard deviation
108110
let mean = times.iter().map(|d| d.as_nanos() as f64).sum::<f64>() / times.len() as f64;

0 commit comments

Comments
 (0)