benchforge 0.1.0 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/BenchRunner-BLfGX2wQ.d.mts +225 -0
- package/dist/HeapSampler-BX3de22o.mjs +54 -0
- package/dist/HeapSampler-BX3de22o.mjs.map +1 -0
- package/dist/TimingUtils-D4z1jpp2.mjs +599 -0
- package/dist/TimingUtils-D4z1jpp2.mjs.map +1 -0
- package/dist/bin/benchforge.d.mts +1 -0
- package/dist/bin/benchforge.mjs +1 -1
- package/dist/index.d.mts +707 -0
- package/dist/index.mjs +2 -1
- package/dist/runners/WorkerScript.d.mts +39 -0
- package/dist/runners/WorkerScript.mjs +158 -0
- package/dist/runners/WorkerScript.mjs.map +1 -0
- package/dist/{src-CGuaC3Wo.mjs → src-D7zxOFGA.mjs} +17 -607
- package/dist/src-D7zxOFGA.mjs.map +1 -0
- package/package.json +1 -1
- package/src/cli/CliArgs.ts +7 -11
- package/src/runners/RunnerOrchestrator.ts +11 -7
- package/src/table-util/Formatters.ts +1 -1
- package/dist/src-CGuaC3Wo.mjs.map +0 -1
package/dist/index.mjs
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
-
import { A as timeSection, B as parseCliArgs, C as adaptiveSection, D as gcStatsSection, E as gcSection, F as generateHtmlReport, G as truncate, H as formatBytes, I as formatDateWithTimezone, J as
|
|
1
|
+
import { A as timeSection, B as parseCliArgs, C as adaptiveSection, D as gcStatsSection, E as gcSection, F as generateHtmlReport, G as truncate, H as formatBytes, I as formatDateWithTimezone, J as loadCaseData, K as isStatefulVariant, L as prepareHtmlData, M as formatConvergence, N as filterMatrix, O as optSection, P as parseMatrixFilter, R as exportPerfettoTrace, S as reportMatrixResults, T as cpuSection, U as integer, V as reportResults, W as timeMs, Y as loadCasesModule, _ as runDefaultMatrixBench, a as cliToMatrixOptions, b as gcStatsColumns, c as exportReports, d as matrixToReportGroups, f as parseBenchArgs, g as runDefaultBench, h as runBenchmarks, i as benchExports, j as totalTimeSection, k as runsSection, l as hasField, m as reportOptStatus, n as getBaselineVersion, o as defaultMatrixReport, p as printHeapReports, q as runMatrix, r as getCurrentGitVersion, s as defaultReport, t as formatGitVersion, u as matrixBenchExports, v as runMatrixSuite, w as buildGenericSections, x as heapTotalColumn, y as gcPauseColumn, z as defaultCliArgs } from "./src-D7zxOFGA.mjs";
|
|
2
|
+
import { u as average } from "./TimingUtils-D4z1jpp2.mjs";
|
|
2
3
|
|
|
3
4
|
export { adaptiveSection, average, benchExports, buildGenericSections, cliToMatrixOptions, cpuSection, defaultCliArgs, defaultMatrixReport, defaultReport, exportPerfettoTrace, exportReports, filterMatrix, formatBytes, formatConvergence, formatDateWithTimezone, formatGitVersion, gcPauseColumn, gcSection, gcStatsColumns, gcStatsSection, generateHtmlReport, getBaselineVersion, getCurrentGitVersion, hasField, heapTotalColumn, integer, isStatefulVariant, loadCaseData, loadCasesModule, matrixBenchExports, matrixToReportGroups, optSection, parseBenchArgs, parseCliArgs, parseMatrixFilter, prepareHtmlData, printHeapReports, reportMatrixResults, reportOptStatus, reportResults, runBenchmarks, runDefaultBench, runDefaultMatrixBench, runMatrix, runMatrixSuite, runsSection, timeMs, timeSection, totalTimeSection, truncate };
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { a as MeasuredResults, i as BenchmarkSpec, o as HeapProfile, t as RunnerOptions } from "../BenchRunner-BLfGX2wQ.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/runners/CreateRunner.d.ts
|
|
4
|
+
type KnownRunner = "basic";
|
|
5
|
+
//#endregion
|
|
6
|
+
//#region src/runners/WorkerScript.d.ts
|
|
7
|
+
/** Message sent to worker process to start a benchmark run. */
|
|
8
|
+
interface RunMessage {
|
|
9
|
+
type: "run";
|
|
10
|
+
spec: BenchmarkSpec;
|
|
11
|
+
runnerName: KnownRunner;
|
|
12
|
+
options: RunnerOptions;
|
|
13
|
+
fnCode?: string;
|
|
14
|
+
modulePath?: string;
|
|
15
|
+
exportName?: string;
|
|
16
|
+
setupExportName?: string;
|
|
17
|
+
params?: unknown;
|
|
18
|
+
variantDir?: string;
|
|
19
|
+
variantId?: string;
|
|
20
|
+
caseData?: unknown;
|
|
21
|
+
caseId?: string;
|
|
22
|
+
casesModule?: string;
|
|
23
|
+
}
|
|
24
|
+
/** Message returned from worker process with benchmark results. */
|
|
25
|
+
interface ResultMessage {
|
|
26
|
+
type: "result";
|
|
27
|
+
results: MeasuredResults[];
|
|
28
|
+
heapProfile?: HeapProfile;
|
|
29
|
+
}
|
|
30
|
+
/** Message returned from worker process when benchmark fails. */
|
|
31
|
+
interface ErrorMessage {
|
|
32
|
+
type: "error";
|
|
33
|
+
error: string;
|
|
34
|
+
stack?: string;
|
|
35
|
+
}
|
|
36
|
+
type WorkerMessage = RunMessage | ResultMessage | ErrorMessage;
|
|
37
|
+
//#endregion
|
|
38
|
+
export { ErrorMessage, ResultMessage, RunMessage, WorkerMessage };
|
|
39
|
+
//# sourceMappingURL=WorkerScript.d.mts.map
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { c as createAdaptiveWrapper, i as createRunner, n as getElapsed, p as variantModuleUrl, r as getPerfNow, t as debugWorkerTiming } from "../TimingUtils-D4z1jpp2.mjs";
|
|
3
|
+
|
|
4
|
+
//#region src/runners/WorkerScript.ts
|
|
5
|
+
const workerStartTime = getPerfNow();
|
|
6
|
+
const maxLifetime = 300 * 1e3;
|
|
7
|
+
/**
|
|
8
|
+
* Worker process for isolated benchmark execution.
|
|
9
|
+
* Uses eval() safely in isolated child process with trusted code.
|
|
10
|
+
*/
|
|
11
|
+
process.on("message", async (message) => {
|
|
12
|
+
if (message.type !== "run") return;
|
|
13
|
+
logTiming(`Processing ${message.spec.name} with ${message.runnerName}`);
|
|
14
|
+
try {
|
|
15
|
+
const start = getPerfNow();
|
|
16
|
+
const baseRunner = await createRunner(message.runnerName);
|
|
17
|
+
const runner = message.options.adaptive ? createAdaptiveWrapper(baseRunner, message.options) : baseRunner;
|
|
18
|
+
logTiming("Runner created in", getElapsed(start));
|
|
19
|
+
const benchStart = getPerfNow();
|
|
20
|
+
if (message.options.heapSample) {
|
|
21
|
+
const { withHeapSampling } = await import("../HeapSampler-BX3de22o.mjs");
|
|
22
|
+
const { result: results, profile: heapProfile } = await withHeapSampling({
|
|
23
|
+
samplingInterval: message.options.heapInterval,
|
|
24
|
+
stackDepth: message.options.heapDepth
|
|
25
|
+
}, async () => {
|
|
26
|
+
const { fn, params } = await resolveBenchmarkFn(message);
|
|
27
|
+
return runner.runBench({
|
|
28
|
+
...message.spec,
|
|
29
|
+
fn
|
|
30
|
+
}, message.options, params);
|
|
31
|
+
});
|
|
32
|
+
logTiming("Benchmark execution took", getElapsed(benchStart));
|
|
33
|
+
sendAndExit({
|
|
34
|
+
type: "result",
|
|
35
|
+
results,
|
|
36
|
+
heapProfile
|
|
37
|
+
}, 0);
|
|
38
|
+
} else {
|
|
39
|
+
const { fn, params } = await resolveBenchmarkFn(message);
|
|
40
|
+
const results = await runner.runBench({
|
|
41
|
+
...message.spec,
|
|
42
|
+
fn
|
|
43
|
+
}, message.options, params);
|
|
44
|
+
logTiming("Benchmark execution took", getElapsed(benchStart));
|
|
45
|
+
sendAndExit({
|
|
46
|
+
type: "result",
|
|
47
|
+
results
|
|
48
|
+
}, 0);
|
|
49
|
+
}
|
|
50
|
+
} catch (error) {
|
|
51
|
+
sendAndExit(createErrorMessage(error), 1);
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
setTimeout(() => {
|
|
55
|
+
console.error("WorkerScript: Maximum lifetime exceeded, exiting");
|
|
56
|
+
process.exit(1);
|
|
57
|
+
}, maxLifetime);
|
|
58
|
+
process.stdin.pause();
|
|
59
|
+
/** Log timing with consistent format */
|
|
60
|
+
const logTiming = debugWorkerTiming ? _logTiming : () => {};
|
|
61
|
+
function _logTiming(operation, duration) {
|
|
62
|
+
if (duration === void 0) console.log(`[Worker] ${operation}`);
|
|
63
|
+
else console.log(`[Worker] ${operation} ${duration.toFixed(1)}ms`);
|
|
64
|
+
}
|
|
65
|
+
/** Send message and exit with duration log */
|
|
66
|
+
function sendAndExit(msg, exitCode) {
|
|
67
|
+
process.send(msg, void 0, void 0, (err) => {
|
|
68
|
+
if (err) {
|
|
69
|
+
const kind = msg.type === "result" ? "results" : "error message";
|
|
70
|
+
console.error(`[Worker] Error sending ${kind}:`, err);
|
|
71
|
+
}
|
|
72
|
+
logTiming(`Total worker duration${exitCode === 0 ? "" : " (error)"}:`, getElapsed(workerStartTime));
|
|
73
|
+
process.exit(exitCode);
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
/** Resolve benchmark function from message (variant dir, module path, or fnCode) */
|
|
77
|
+
async function resolveBenchmarkFn(message) {
|
|
78
|
+
if (message.variantDir && message.variantId) return importVariantModule(message);
|
|
79
|
+
if (message.modulePath) return importBenchmarkWithSetup(message);
|
|
80
|
+
return {
|
|
81
|
+
fn: reconstructFunction(message.fnCode),
|
|
82
|
+
params: message.params
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
/** Import variant from directory and prepare benchmark function */
|
|
86
|
+
async function importVariantModule(message) {
|
|
87
|
+
const { variantDir, variantId, caseId, casesModule } = message;
|
|
88
|
+
let { caseData } = message;
|
|
89
|
+
const moduleUrl = variantModuleUrl(variantDir, variantId);
|
|
90
|
+
logTiming(`Importing variant ${variantId} from ${variantDir}`);
|
|
91
|
+
if (casesModule && caseId) caseData = (await loadCaseFromModule(casesModule, caseId)).data;
|
|
92
|
+
const { setup, run } = await import(moduleUrl);
|
|
93
|
+
if (typeof run !== "function") throw new Error(`Variant '${variantId}' must export 'run' function`);
|
|
94
|
+
if (typeof setup === "function") {
|
|
95
|
+
logTiming(`Calling setup for ${variantId}`);
|
|
96
|
+
const state = await setup(caseData);
|
|
97
|
+
return {
|
|
98
|
+
fn: () => run(state),
|
|
99
|
+
params: void 0
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
return {
|
|
103
|
+
fn: () => run(caseData),
|
|
104
|
+
params: void 0
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
/** Load case data from a cases module */
|
|
108
|
+
async function loadCaseFromModule(casesModuleUrl, caseId) {
|
|
109
|
+
logTiming(`Loading case '${caseId}' from ${casesModuleUrl}`);
|
|
110
|
+
const module = await import(casesModuleUrl);
|
|
111
|
+
if (typeof module.loadCase === "function") return module.loadCase(caseId);
|
|
112
|
+
return { data: caseId };
|
|
113
|
+
}
|
|
114
|
+
/** Import benchmark function and optionally run setup */
|
|
115
|
+
async function importBenchmarkWithSetup(message) {
|
|
116
|
+
const { modulePath, exportName, setupExportName, params } = message;
|
|
117
|
+
logTiming(`Importing from ${modulePath}${exportName ? ` (${exportName})` : ""}`);
|
|
118
|
+
const module = await import(modulePath);
|
|
119
|
+
const fn = getModuleExport(module, exportName, modulePath);
|
|
120
|
+
if (setupExportName) {
|
|
121
|
+
logTiming(`Calling setup: ${setupExportName}`);
|
|
122
|
+
return {
|
|
123
|
+
fn,
|
|
124
|
+
params: await getModuleExport(module, setupExportName, modulePath)(params)
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
return {
|
|
128
|
+
fn,
|
|
129
|
+
params
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
/** Get named or default export from module */
|
|
133
|
+
function getModuleExport(module, exportName, modulePath) {
|
|
134
|
+
const fn = exportName ? module[exportName] : module.default || module;
|
|
135
|
+
if (typeof fn !== "function") {
|
|
136
|
+
const name = exportName || "default";
|
|
137
|
+
throw new Error(`Export '${name}' from ${modulePath} is not a function`);
|
|
138
|
+
}
|
|
139
|
+
return fn;
|
|
140
|
+
}
|
|
141
|
+
/** Reconstruct function from string code */
|
|
142
|
+
function reconstructFunction(fnCode) {
|
|
143
|
+
const fn = eval(`(${fnCode})`);
|
|
144
|
+
if (typeof fn !== "function") throw new Error("Reconstructed code is not a function");
|
|
145
|
+
return fn;
|
|
146
|
+
}
|
|
147
|
+
/** Create error message from exception */
|
|
148
|
+
function createErrorMessage(error) {
|
|
149
|
+
return {
|
|
150
|
+
type: "error",
|
|
151
|
+
error: error instanceof Error ? error.message : String(error),
|
|
152
|
+
stack: error instanceof Error ? error.stack : void 0
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
//#endregion
|
|
157
|
+
export { };
|
|
158
|
+
//# sourceMappingURL=WorkerScript.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WorkerScript.mjs","names":[],"sources":["../../src/runners/WorkerScript.ts"],"sourcesContent":["#!/usr/bin/env node\nimport type { BenchmarkFunction, BenchmarkSpec } from \"../Benchmark.ts\";\nimport type { HeapProfile } from \"../heap-sample/HeapSampler.ts\";\nimport type { MeasuredResults } from \"../MeasuredResults.ts\";\nimport { variantModuleUrl } from \"../matrix/VariantLoader.ts\";\nimport {\n type AdaptiveOptions,\n createAdaptiveWrapper,\n} from \"./AdaptiveWrapper.ts\";\nimport type { RunnerOptions } from \"./BenchRunner.ts\";\nimport { createRunner, type KnownRunner } from \"./CreateRunner.ts\";\nimport { debugWorkerTiming, getElapsed, getPerfNow } from \"./TimingUtils.ts\";\n\nconst workerStartTime = getPerfNow();\nconst maxLifetime = 5 * 60 * 1000; // 5 minutes\n\n/** Message sent to worker process to start a benchmark run. */\nexport interface RunMessage {\n type: \"run\";\n spec: BenchmarkSpec;\n runnerName: KnownRunner;\n options: RunnerOptions;\n fnCode?: string; // Made optional - either fnCode or modulePath is required\n modulePath?: string; // Path to module for dynamic import\n exportName?: string; // Export name from module\n setupExportName?: string; // Setup function export name - called once, result passed to fn\n params?: unknown;\n // Variant directory mode (BenchMatrix)\n variantDir?: string; // Directory URL containing variant .ts files\n variantId?: string; // Variant filename (without .ts)\n caseData?: unknown; // Data to pass to variant\n caseId?: string; // Case identifier\n casesModule?: string; // URL to cases module (exports cases[] and loadCase())\n}\n\n/** Message returned from worker process with benchmark results. */\nexport interface ResultMessage {\n type: \"result\";\n results: MeasuredResults[];\n heapProfile?: HeapProfile;\n}\n\n/** Message returned from worker process when benchmark fails. */\nexport interface ErrorMessage {\n type: \"error\";\n error: string;\n stack?: string;\n}\n\nexport type WorkerMessage = RunMessage | ResultMessage | ErrorMessage;\n\n/**\n * Worker process for isolated benchmark execution.\n * Uses eval() safely in isolated child process with trusted code.\n */\nprocess.on(\"message\", async (message: RunMessage) => {\n if (message.type !== \"run\") return;\n\n logTiming(`Processing ${message.spec.name} with ${message.runnerName}`);\n\n try {\n const start = getPerfNow();\n const baseRunner = await createRunner(message.runnerName);\n\n const runner = (message.options as any).adaptive\n ? createAdaptiveWrapper(baseRunner, message.options as AdaptiveOptions)\n : baseRunner;\n\n logTiming(\"Runner created in\", getElapsed(start));\n\n const benchStart = getPerfNow();\n\n // Run with heap sampling if enabled (covers module import + execution)\n if (message.options.heapSample) {\n const { withHeapSampling } = await import(\n \"../heap-sample/HeapSampler.ts\"\n );\n const heapOpts = {\n samplingInterval: message.options.heapInterval,\n stackDepth: message.options.heapDepth,\n };\n const { result: results, profile: heapProfile } = await withHeapSampling(\n heapOpts,\n async () => {\n const { fn, params } = await resolveBenchmarkFn(message);\n return runner.runBench(\n { ...message.spec, fn },\n message.options,\n params,\n );\n },\n );\n logTiming(\"Benchmark execution took\", getElapsed(benchStart));\n sendAndExit({ type: \"result\", results, heapProfile }, 0);\n } else {\n const { fn, params } = await resolveBenchmarkFn(message);\n const results = await runner.runBench(\n { ...message.spec, fn },\n message.options,\n params,\n );\n logTiming(\"Benchmark execution took\", getElapsed(benchStart));\n sendAndExit({ type: \"result\", results }, 0);\n }\n } catch (error) {\n sendAndExit(createErrorMessage(error), 1);\n }\n});\n\n// Exit after 5 minutes to prevent zombie processes\nsetTimeout(() => {\n console.error(\"WorkerScript: Maximum lifetime exceeded, exiting\");\n process.exit(1);\n}, maxLifetime);\n\nprocess.stdin.pause();\n\n/** Log timing with consistent format */\nconst logTiming = debugWorkerTiming ? _logTiming : () => {};\nfunction _logTiming(operation: string, duration?: number) {\n if (duration === undefined) {\n console.log(`[Worker] ${operation}`);\n } else {\n console.log(`[Worker] ${operation} ${duration.toFixed(1)}ms`);\n }\n}\n\n/** Send message and exit with duration log */\nfunction sendAndExit(msg: ResultMessage | ErrorMessage, exitCode: number) {\n process.send!(msg, undefined, undefined, (err: Error | null): void => {\n if (err) {\n const kind = msg.type === \"result\" ? \"results\" : \"error message\";\n console.error(`[Worker] Error sending ${kind}:`, err);\n }\n const suffix = exitCode === 0 ? \"\" : \" (error)\";\n logTiming(`Total worker duration${suffix}:`, getElapsed(workerStartTime));\n process.exit(exitCode);\n });\n}\n\ninterface BenchmarkImportResult {\n fn: BenchmarkFunction;\n params: unknown;\n}\n\n/** Resolve benchmark function from message (variant dir, module path, or fnCode) */\nasync function resolveBenchmarkFn(\n message: RunMessage,\n): Promise<BenchmarkImportResult> {\n if (message.variantDir && message.variantId) {\n return importVariantModule(message);\n }\n if (message.modulePath) {\n return importBenchmarkWithSetup(message);\n }\n return { fn: reconstructFunction(message.fnCode!), params: message.params };\n}\n\n/** Import variant from directory and prepare benchmark function */\nasync function importVariantModule(\n message: RunMessage,\n): Promise<BenchmarkImportResult> {\n const { variantDir, variantId, caseId, casesModule } = message;\n let { caseData } = message;\n const moduleUrl = variantModuleUrl(variantDir!, variantId!);\n logTiming(`Importing variant ${variantId} from ${variantDir}`);\n\n if (casesModule && caseId) {\n caseData = (await loadCaseFromModule(casesModule, caseId)).data;\n }\n\n const module = await import(moduleUrl);\n const { setup, run } = module;\n\n if (typeof run !== \"function\") {\n throw new Error(`Variant '${variantId}' must export 'run' function`);\n }\n\n // Stateful variant: setup returns state, run receives state\n if (typeof setup === \"function\") {\n logTiming(`Calling setup for ${variantId}`);\n const state = await setup(caseData);\n return { fn: () => run(state), params: undefined };\n }\n\n // Stateless variant: run receives caseData directly\n return { fn: () => run(caseData), params: undefined };\n}\n\n/** Load case data from a cases module */\nasync function loadCaseFromModule(\n casesModuleUrl: string,\n caseId: string,\n): Promise<{ data: unknown; metadata?: Record<string, unknown> }> {\n logTiming(`Loading case '${caseId}' from ${casesModuleUrl}`);\n const module = await import(casesModuleUrl);\n if (typeof module.loadCase === \"function\") {\n return module.loadCase(caseId);\n }\n return { data: caseId };\n}\n\n/** Import benchmark function and optionally run setup */\nasync function importBenchmarkWithSetup(\n message: RunMessage,\n): Promise<BenchmarkImportResult> {\n const { modulePath, exportName, setupExportName, params } = message;\n logTiming(\n `Importing from ${modulePath}${exportName ? ` (${exportName})` : \"\"}`,\n );\n const module = await import(modulePath!);\n\n const fn = getModuleExport(module, exportName, modulePath!);\n\n if (setupExportName) {\n logTiming(`Calling setup: ${setupExportName}`);\n const setupFn = getModuleExport(module, setupExportName, modulePath!);\n const setupResult = await setupFn(params);\n return { fn, params: setupResult };\n }\n\n return { fn, params };\n}\n\n/** Get named or default export from module */\nfunction getModuleExport(\n module: any,\n exportName: string | undefined,\n modulePath: string,\n): BenchmarkFunction {\n const fn = exportName ? module[exportName] : module.default || module;\n if (typeof fn !== \"function\") {\n const name = exportName || \"default\";\n throw new Error(`Export '${name}' from ${modulePath} is not a function`);\n }\n return fn;\n}\n\n/** Reconstruct function from string code */\nfunction reconstructFunction(fnCode: string): BenchmarkFunction {\n // biome-ignore lint/security/noGlobalEval: Necessary for worker process isolation, code is from trusted source\n const fn = eval(`(${fnCode})`); // eslint-disable-line no-eval\n if (typeof fn !== \"function\") {\n throw new Error(\"Reconstructed code is not a function\");\n }\n return fn;\n}\n\n/** Create error message from exception */\nfunction createErrorMessage(error: unknown): ErrorMessage {\n return {\n type: \"error\",\n error: error instanceof Error ? error.message : String(error),\n stack: error instanceof Error ? error.stack : undefined,\n };\n}\n"],"mappings":"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"}
|