tg-bot-ts/src/systems/benchmark.ts
2026-06-10 04:44:57 +01:00

82 lines
No EOL
2.4 KiB
TypeScript

/**
* Benchmark — lightweight performance profiling.
*
* Usage:
* import { Benchmark } from "@systems/benchmark";
*
* const bench = Benchmark.start("vote");
* // ... do work ...
* bench.mark("resolveUser"); // logs: [vote] resolveUser: 12ms
* // ... more work ...
* bench.mark("updatePoll"); // logs: [vote] updatePoll: 145ms
* bench.end(); // logs: [vote] total: 157ms
*
* // One-liner:
* const result = await Benchmark.measure("vote", async () => {
* return await doSomething();
* });
*/
import { Logger, logLevel } from "@systems/logger";
const log = Logger.for("benchmark");
// ─── Active benchmark instance ────────────────────────────────────────────────
export interface BenchmarkInstance {
/** Log time since last mark (or start). */
mark(label: string): void;
/** Log total time since start. */
end(): number;
}
function createBenchmark(name: string, enabled: boolean): BenchmarkInstance {
let last = Date.now();
const t0 = last;
return {
mark(label: string): void {
if (!enabled) return;
const now = Date.now();
const delta = now - last;
last = now;
log.debug(`[${name}] ${label}: ${delta}ms`);
},
end(): number {
const total = Date.now() - t0;
if (enabled) log.debug(`[${name}] total: ${total}ms`);
return total;
},
};
}
// ─── Namespace ────────────────────────────────────────────────────────────────
// Only profile when LOG_LEVEL=debug
const _enabled = () => logLevel() === "DEBUG";
export const Benchmark = {
/**
* Start a named benchmark.
* Only active when LOG_LEVEL=debug — zero overhead in production.
*/
start(name: string): BenchmarkInstance {
return createBenchmark(name, _enabled());
},
/**
* Measure and return the result of an async function.
*/
async measure<T>(name: string, fn: () => Promise<T>): Promise<T> {
const bench = Benchmark.start(name);
try {
const result = await fn();
bench.end();
return result;
} catch (err) {
bench.end();
throw err;
}
},
};