From e7ae6bba8e51af6f3690942ff04162c15fb2cf72 Mon Sep 17 00:00:00 2001 From: Bortlesboat Date: Sat, 21 Mar 2026 09:34:09 -0400 Subject: [PATCH] fix: benchmark scores clamped to 0% for below-average hardware The log2 normalization formula `50 * (1 + log2(ratio))` produces negative values (clamped to 0) whenever the measured value is less than half the reference. For example, a CPU scoring 1993 events/sec against a 5000 reference gives ratio=0.4, log2(0.4)=-1.32, score=-16 -> 0%. Fix by dividing log2 by 3 to widen the usable range. This preserves the 50% score at the reference value while allowing below-average hardware to receive proportional non-zero scores (e.g., 28% for the CPU above). Also adds debug logging for CPU sysbench output parsing to aid future diagnosis of parsing issues. Fixes #415 --- admin/app/services/benchmark_service.ts | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/admin/app/services/benchmark_service.ts b/admin/app/services/benchmark_service.ts index 715d729..80247f7 100644 --- a/admin/app/services/benchmark_service.ts +++ b/admin/app/services/benchmark_service.ts @@ -571,10 +571,10 @@ export class BenchmarkService { */ private _normalizeScore(value: number, reference: number): number { if (value <= 0) return 0 - // Log scale: score = 50 * (1 + log2(value/reference)) - // This gives 50 at reference value, scales logarithmically + // Log scale with widened range: dividing log2 by 3 prevents scores from + // clamping to 0% for below-average hardware. Gives 50% at reference value. const ratio = value / reference - const score = 50 * (1 + Math.log2(Math.max(0.01, ratio))) + const score = 50 * (1 + Math.log2(Math.max(0.01, ratio)) / 3) return Math.min(100, Math.max(0, score)) / 100 } @@ -583,9 +583,9 @@ export class BenchmarkService { */ private _normalizeScoreInverse(value: number, reference: number): number { if (value <= 0) return 1 - // Inverse: lower values = higher scores + // Inverse: lower values = higher scores, with widened log range const ratio = reference / value - const score = 50 * (1 + Math.log2(Math.max(0.01, ratio))) + const score = 50 * (1 + Math.log2(Math.max(0.01, ratio)) / 3) return Math.min(100, Math.max(0, score)) / 100 } @@ -619,6 +619,7 @@ export class BenchmarkService { const eventsMatch = output.match(/events per second:\s*([\d.]+)/i) const totalTimeMatch = output.match(/total time:\s*([\d.]+)s/i) const totalEventsMatch = output.match(/total number of events:\s*(\d+)/i) + logger.debug(`[BenchmarkService] CPU output parsing - events/s: ${eventsMatch?.[1]}, total_time: ${totalTimeMatch?.[1]}, total_events: ${totalEventsMatch?.[1]}`) return { events_per_second: eventsMatch ? parseFloat(eventsMatch[1]) : 0,