// SPDX-License-Identifier: AGPL-3.0-only // Copyright (C) 2026 Giancarlo Erra - Altaire Limited /** * scripts/benchmark-graph.ts * * Smoke benchmark: builds the code graph + symbol graph for a target * repository and prints timing / count / memory results as JSON. * * Usage: * npx tsx scripts/benchmark-graph.ts * npx tsx scripts/benchmark-graph.ts # defaults to cwd * * The script also prints a short Markdown line suitable for pasting into * DEVELOPER.md's "Real-world benchmark numbers" table. */ import path from "node:path"; import process from "node:process"; import { projectIdFromPath } from "../src/config.js"; import { rebuildGraph } from "../src/services/code-graph.js"; import { setLogLevel } from "../src/services/logger.js"; import { loadSymbolGraphMeta } from "../src/services/symbol-graph-store.js"; import { waitForQdrant } from "../tests/helpers/setup.js"; async function main(): Promise { setLogLevel("warn"); // keep stderr quiet for clean JSON output const target = path.resolve(process.argv[2] ?? process.cwd()); await waitForQdrant(); const projectId = projectIdFromPath(target); const memBefore = process.memoryUsage().heapUsed; const start = Date.now(); const graph = await rebuildGraph(target); const elapsedMs = Date.now() - start; const memAfter = process.memoryUsage().heapUsed; const meta = await loadSymbolGraphMeta(projectId); const result = { target, projectId, elapsedMs, fileCount: graph.nodes.length, edgeCount: graph.edges.length, symbolCount: meta?.symbolCount ?? null, callEdgeCount: meta?.edgeCount ?? null, unresolvedPct: meta?.unresolvedPct ?? null, heapDeltaMb: Math.round(((memAfter - memBefore) / 1024 / 1024) * 100) / 100, rssMb: Math.round((process.memoryUsage().rss / 1024 / 1024) * 100) / 100, nodeVersion: process.version, timestamp: new Date().toISOString(), }; process.stdout.write(`${JSON.stringify(result, null, 2)}\n`); // Also emit a Markdown row. const date = result.timestamp.slice(0, 10); const md = `| ${date} | \`${path.basename(target)}\` | ${result.fileCount} | ${result.symbolCount ?? "—"} | ${result.callEdgeCount ?? "—"} | ${(elapsedMs / 1000).toFixed(2)} s | ${result.rssMb} MB |`; process.stderr.write(`\nMarkdown row:\n${md}\n`); } main().catch((err) => { process.stderr.write(`benchmark failed: ${err instanceof Error ? err.message : String(err)}\n`); process.exitCode = 1; });