Skip to content

Commit 0138915

Browse files
authored
perf(bench): exclude resolution fixtures from incremental-benchmark sweep (#1131)
The incremental benchmark walks the repo root, which pulls hand-annotated resolution-benchmark fixtures into the corpus. A single heavy grammar (tree-sitter-verilog #1107) added ~850ms to fullBuildMs — the cost is real but unrelated to shared code paths the benchmark is meant to track. Add an optional exclude glob array to BuildGraphOpts, merged into config.exclude in setupPipeline so both the JS pipeline and the native orchestrator (which receives ctx.config as JSON) honor it. Pass 'tests/benchmarks/resolution/fixtures/**' from the benchmark script so future language PRs don't silently inflate timings, and remove the 3.10.0:Full build entry from KNOWN_REGRESSIONS now that the cause is addressed. Closes #1112
1 parent f06a213 commit 0138915

4 files changed

Lines changed: 24 additions & 19 deletions

File tree

scripts/incremental-benchmark.ts

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,15 @@ const PROBE_FILE = path.join(root, 'src', 'domain', 'queries.ts');
181181
// CI-amplified false regressions on sub-30ms metrics like No-op rebuild.
182182
const WARMUP_RUNS = 2;
183183

184+
// Resolution-benchmark fixtures live under the repo root and get pulled into
185+
// every self-build sweep. They are hand-annotated test corpora — not real
186+
// codegraph code — and a single heavy grammar (e.g. tree-sitter-verilog) can
187+
// add hundreds of milliseconds to fullBuildMs purely from fixture parsing
188+
// (#1112). Exclude them so adding native support for a new language doesn't
189+
// silently inflate the incremental-benchmark numbers.
190+
const BENCH_EXCLUDE = ['tests/benchmarks/resolution/fixtures/**'];
191+
const BUILD_OPTS = { engine, exclude: BENCH_EXCLUDE };
192+
184193
function median(arr) {
185194
const sorted = [...arr].sort((a, b) => a - b);
186195
const mid = Math.floor(sorted.length / 2);
@@ -194,7 +203,7 @@ const fullTimings = [];
194203
for (let i = 0; i < RUNS; i++) {
195204
if (fs.existsSync(dbPath)) fs.unlinkSync(dbPath);
196205
const start = performance.now();
197-
await buildGraph(root, { engine, incremental: false });
206+
await buildGraph(root, { ...BUILD_OPTS, incremental: false });
198207
fullTimings.push(performance.now() - start);
199208
}
200209
const fullBuildMs = Math.round(median(fullTimings));
@@ -203,12 +212,12 @@ const fullBuildMs = Math.round(median(fullTimings));
203212
let noopRebuildMs = null;
204213
try {
205214
for (let i = 0; i < WARMUP_RUNS; i++) {
206-
await buildGraph(root, { engine, incremental: true });
215+
await buildGraph(root, { ...BUILD_OPTS, incremental: true });
207216
}
208217
const noopTimings = [];
209218
for (let i = 0; i < RUNS; i++) {
210219
const start = performance.now();
211-
await buildGraph(root, { engine, incremental: true });
220+
await buildGraph(root, { ...BUILD_OPTS, incremental: true });
212221
noopTimings.push(performance.now() - start);
213222
}
214223
noopRebuildMs = Math.round(median(noopTimings));
@@ -223,13 +232,13 @@ let oneFilePhases = null;
223232
try {
224233
for (let i = 0; i < WARMUP_RUNS; i++) {
225234
fs.writeFileSync(PROBE_FILE, original + `\n// warmup-${i}\n`);
226-
await buildGraph(root, { engine, incremental: true });
235+
await buildGraph(root, { ...BUILD_OPTS, incremental: true });
227236
}
228237
const oneFileRuns = [];
229238
for (let i = 0; i < RUNS; i++) {
230239
fs.writeFileSync(PROBE_FILE, original + `\n// probe-${i}\n`);
231240
const start = performance.now();
232-
const res = await buildGraph(root, { engine, incremental: true });
241+
const res = await buildGraph(root, { ...BUILD_OPTS, incremental: true });
233242
oneFileRuns.push({ ms: performance.now() - start, phases: res?.phases || null });
234243
}
235244
oneFileRuns.sort((a, b) => a.ms - b.ms);
@@ -241,7 +250,7 @@ try {
241250
} finally {
242251
fs.writeFileSync(PROBE_FILE, original);
243252
try {
244-
await buildGraph(root, { engine, incremental: true });
253+
await buildGraph(root, { ...BUILD_OPTS, incremental: true });
245254
} catch {
246255
// Cleanup rebuild failed — probe file is already restored, move on
247256
}

src/domain/graph/builder/pipeline.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,9 @@ function setupPipeline(ctx: PipelineContext): void {
185185
initSchema(ctx.db);
186186

187187
ctx.config = loadConfig(ctx.rootDir);
188+
if (ctx.opts.exclude && ctx.opts.exclude.length > 0) {
189+
ctx.config = { ...ctx.config, exclude: [...ctx.config.exclude, ...ctx.opts.exclude] };
190+
}
188191
ctx.incremental =
189192
ctx.opts.incremental !== false && ctx.config.build && ctx.config.build.incremental !== false;
190193

src/types.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1064,6 +1064,12 @@ export interface BuildGraphOpts {
10641064
cfg?: boolean;
10651065
scope?: string[];
10661066
skipRegistry?: boolean;
1067+
/**
1068+
* Extra exclude globs appended to `config.exclude`. Lets benchmark scripts
1069+
* skip fixture directories that bloat self-build timings without permanently
1070+
* affecting `.codegraphrc.json` for normal users.
1071+
*/
1072+
exclude?: string[];
10671073
}
10681074

10691075
/** Build timing result from buildGraph. */

tests/benchmarks/regression-guard.test.ts

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -176,18 +176,6 @@ const SKIP_VERSIONS = new Set(['3.8.0']);
176176
* absolute delta 10.4ms exactly at the MIN_ABSOLUTE_DELTA floor. Exempt
177177
* this release; remove once 3.11.0+ data confirms stabilization.
178178
*
179-
* - 3.10.0:Full build — adding native Verilog support (#1107) pulled the
180-
* 4 `.v` resolution-benchmark fixtures into the corpus the incremental
181-
* benchmark sweeps (it runs against the repo root). tree-sitter-verilog
182-
* is a large grammar (SystemVerilog is one of the heaviest in the
183-
* tree-sitter ecosystem) so each file costs noticeably more than the
184-
* other fixture languages. Local measurement: 1959 → 2809 (+43%, run
185-
* 25716010487). The cost is real and structural — not a regression in
186-
* shared code paths. Resolution: either exclude `tests/benchmarks/
187-
* resolution/fixtures/verilog/**` from the benchmark sweep or accept the
188-
* one-time bump as the cost of supporting Verilog. Tracked separately;
189-
* exempt this release.
190-
*
191179
* - 3.10.0:Query time — cumulative effect of adding two native extractors
192180
* (Solidity #1100 + R #1102) in quick succession. Neither tripped the
193181
* threshold individually (Solidity PR's Query time stayed at 49ms, R PR
@@ -230,7 +218,6 @@ const KNOWN_REGRESSIONS = new Set([
230218
'3.10.0:fnDeps depth 1',
231219
'3.10.0:fnDeps depth 3',
232220
'3.10.0:fnDeps depth 5',
233-
'3.10.0:Full build',
234221
'3.10.0:Query time',
235222
]);
236223

0 commit comments

Comments
 (0)