Files
nest/tools/benchmarks/check-benchmarks.ts
Micael Levi L. Cavalcante 6bcb3bdcbd style: fix formatting
2023-09-21 17:52:08 -04:00

149 lines
3.7 KiB
TypeScript

import { codechecks, CodeChecksReport } from '@codechecks/client';
import * as bytes from 'bytes';
import { Benchmarks, getBenchmarks, LIBS } from './get-benchmarks';
const markdownTable = require('markdown-table');
const benchmarksKey = 'nest/performance-benchmark';
export default async function checkBenchmarks() {
const currentBenchmarks = await getBenchmarks();
await codechecks.saveValue(benchmarksKey, currentBenchmarks);
if (!codechecks.isPr()) {
return;
}
const baselineBenchmarks =
await codechecks.getValue<Benchmarks>(benchmarksKey);
const report = getCodechecksReport(currentBenchmarks, baselineBenchmarks);
await codechecks.report(report);
}
function getCodechecksReport(
current: Benchmarks,
baseline: Benchmarks | undefined,
): CodeChecksReport {
const diff = getDiff(current, baseline);
const shortDescription = getShortDescription(baseline, diff);
const longDescription = getLongDescription(current, baseline, diff);
return {
name: 'Benchmarks',
status: 'success',
shortDescription,
longDescription,
};
}
function getShortDescription(
baseline: Benchmarks | undefined,
diff: BenchmarksDiff,
): string {
if (!baseline) {
return 'New benchmarks generated';
}
const avgDiff = getAverageDiff(diff);
if (avgDiff > 0) {
return `Performance improved by ${avgDiff.toFixed(
2,
)}% on average, good job!`;
}
if (avgDiff === 0) {
return `No changes in performance detected`;
}
if (avgDiff < 0) {
return `Performance decreased by ${avgDiff.toFixed(
2,
)}% on average, be careful!`;
}
}
function getLongDescription(
current: Benchmarks,
baseline: Benchmarks | undefined,
diff: BenchmarksDiff,
): string {
function printTableRow(id: string, label: string): string[] {
return [
label,
current[id].requestsPerSec.toFixed(0),
current[id].transferPerSec,
baseline ? formatPerc(diff[id].requestsPerSecDiff) : '-',
baseline ? formatPerc(diff[id].transferPerSecDiff) : '-',
];
}
const table = [
['', 'Req/sec', 'Trans/sec', 'Req/sec DIFF', 'Trans/sec DIFF'],
printTableRow('nest', 'Nest-Express'),
printTableRow('nest-fastify', 'Nest-Fastify'),
printTableRow('express', 'Express'),
printTableRow('fastify', 'Fastify'),
];
return markdownTable(table);
}
function getDiff(
current: Benchmarks,
baseline: Benchmarks | undefined,
): BenchmarksDiff {
const diff: BenchmarksDiff = {};
for (const l of LIBS) {
if (!baseline) {
diff[l] = undefined;
continue;
}
const currentValue = current[l];
const baselineValue = baseline[l];
diff[l] = {
requestsPerSecDiff: getRequestDiff(
currentValue.requestsPerSec,
baselineValue.requestsPerSec,
),
transferPerSecDiff: getTransferDiff(
currentValue.transferPerSec,
baselineValue.transferPerSec,
),
};
}
return diff;
}
function getTransferDiff(
currentTransfer: string,
baselineTransfer: string,
): number {
return 1 - bytes.parse(currentTransfer) / bytes.parse(baselineTransfer);
}
function getAverageDiff(diff: BenchmarksDiff) {
return (
(diff['nest'].transferPerSecDiff +
diff['nest'].requestsPerSecDiff +
diff['nest-fastify'].transferPerSecDiff +
diff['nest-fastify'].requestsPerSecDiff) /
4
);
}
function getRequestDiff(currentRequest: number, baselineRequest: number) {
return 1 - currentRequest / baselineRequest;
}
interface BenchmarkDiff {
transferPerSecDiff: number | undefined;
requestsPerSecDiff: number | undefined;
}
interface BenchmarksDiff {
[lib: string]: BenchmarkDiff;
}
function formatPerc(n: number) {
return (n > 0 ? '+' : '') + (n * 100).toFixed(2) + '%';
}