Skip to content

Commit 3091604

Browse files
Mossakaclaude
andcommitted
fix: address review feedback from Copilot
- Guard against division by zero when baseline meanP95 or current p95 is zero (skips comparison instead of producing Infinity/NaN) - Validate --baseline argument: error if flag provided without a path - Fix stderr redirect (2>&1) that would corrupt benchmark-results.json with human-readable progress text mixed into JSON output - Fix cache restore key to use branch-scoped prefix matching instead of overly broad fallback that could pull history from other branches - Add 2 tests for zero p95 edge cases Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent ff81a38 commit 3091604

4 files changed

Lines changed: 46 additions & 7 deletions

File tree

.github/workflows/performance-monitor.yml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,10 @@ jobs:
4848
uses: actions/cache/restore@v4
4949
with:
5050
path: benchmark-history.json
51-
key: benchmark-history-${{ github.ref_name }}
51+
key: benchmark-history-${{ github.ref_name }}-${{ github.run_id }}
5252
restore-keys: |
53-
benchmark-history-
53+
benchmark-history-${{ github.ref_name }}-
54+
benchmark-history-main-
5455
5556
- name: Run benchmarks
5657
id: benchmark
@@ -59,7 +60,7 @@ jobs:
5960
if [ -f benchmark-history.json ]; then
6061
BASELINE_ARG="--baseline benchmark-history.json"
6162
fi
62-
npx tsx scripts/ci/benchmark-performance.ts $BASELINE_ARG > benchmark-results.json 2>&1 || true
63+
npx tsx scripts/ci/benchmark-performance.ts $BASELINE_ARG > benchmark-results.json || true
6364
cat benchmark-results.json
6465
6566
- name: Update benchmark history

scripts/ci/benchmark-performance.ts

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -239,10 +239,17 @@ function benchmarkNetworkCreation(): BenchmarkResult {
239239

240240
function parseBaselineArg(): string | null {
241241
const idx = process.argv.indexOf("--baseline");
242-
if (idx !== -1 && idx + 1 < process.argv.length) {
243-
return process.argv[idx + 1];
242+
if (idx === -1) {
243+
return null;
244244
}
245-
return null;
245+
246+
const value = process.argv[idx + 1];
247+
if (!value || value.startsWith("--")) {
248+
console.error("Error: --baseline requires a file path argument");
249+
process.exit(1);
250+
}
251+
252+
return value;
246253
}
247254

248255
async function main(): Promise<void> {

src/benchmark/history.test.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,33 @@ describe("compareAgainstBaseline", () => {
153153
expect(comparisons).toHaveLength(0);
154154
});
155155

156+
it("skips metrics with zero rolling mean p95 to avoid division by zero", () => {
157+
const history: BenchmarkHistory = {
158+
version: 1,
159+
entries: [makeEntry(0, 0)],
160+
};
161+
const report = makeReport();
162+
const comparisons = compareAgainstBaseline(report, history);
163+
164+
// Both metrics have 0 baseline p95, so they should be skipped
165+
expect(comparisons).toHaveLength(0);
166+
});
167+
168+
it("skips metrics with zero current p95", () => {
169+
const history: BenchmarkHistory = {
170+
version: 1,
171+
entries: [makeEntry(5000, 80)],
172+
};
173+
const report = makeReport({
174+
results: [
175+
{ metric: "container_startup_warm", unit: "ms", values: [0], mean: 0, median: 0, p95: 0, p99: 0 },
176+
],
177+
});
178+
const comparisons = compareAgainstBaseline(report, history);
179+
180+
expect(comparisons).toHaveLength(0);
181+
});
182+
156183
it("skips metrics not in history", () => {
157184
const history: BenchmarkHistory = {
158185
version: 1,

src/benchmark/history.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,11 @@ export function compareAgainstBaseline(
125125

126126
for (const result of report.results) {
127127
const baseline = rolling[result.metric];
128-
if (!baseline || baseline.count === 0) {
128+
if (!baseline || baseline.count === 0 || baseline.meanP95 <= 0) {
129+
continue;
130+
}
131+
132+
if (result.p95 <= 0) {
129133
continue;
130134
}
131135

0 commit comments

Comments
 (0)