Files
tiku-backend.net/tools/performance/compare-baseline.mjs
xiong 290a0c7bd7
Some checks failed
ci / release-gate (push) Has been cancelled
feat(platform): harden governance and approval workflows
2026-08-03 11:43:18 +08:00

31 lines
1.5 KiB
JavaScript

import fs from 'node:fs';
import path from 'node:path';
const [baselineDir, candidateDir] = process.argv.slice(2);
if (!baselineDir || !candidateDir) {
throw new Error('usage: node compare-baseline.mjs <baseline-dir> <candidate-dir>');
}
function median(values) {
const sorted = [...values].sort((left, right) => left - right);
return sorted[Math.floor(sorted.length / 2)];
}
function read(directory) {
const summaries = [1, 2, 3].map((run) => JSON.parse(fs.readFileSync(path.join(directory, `summary-run-${run}.json`), 'utf8')));
return {
throughput: median(summaries.map((summary) => summary.metrics.http_reqs.values.rate)),
p95: median(summaries.map((summary) => summary.metrics.http_req_duration.values['p(95)'])),
p99: median(summaries.map((summary) => summary.metrics.http_req_duration.values['p(99)'])),
failures: summaries.reduce((total, summary) => total + (summary.metrics.http_req_failed?.values?.passes || 0), 0),
dropped: summaries.reduce((total, summary) => total + (summary.metrics.dropped_iterations?.values?.count || 0), 0),
};
}
const baseline = read(baselineDir);
const candidate = read(candidateDir);
const throughputChange = (candidate.throughput - baseline.throughput) / baseline.throughput;
const p95Change = (candidate.p95 - baseline.p95) / baseline.p95;
console.log(JSON.stringify({ baseline, candidate, throughputChange, p95Change }, null, 2));
if (candidate.failures > 0 || candidate.dropped > 0 || throughputChange < -0.05 || p95Change > 0.05) process.exitCode = 1;