Skip to content

perf(compile): cache model attachment on warm and one-edit compiles - #920

Closed
kvlonge wants to merge 3 commits into
mainfrom
perf/chi-442-attachment-cache
Closed

kvlonge wants to merge 3 commits into
mainfrom
perf/chi-442-attachment-cache

Conversation

@kvlonge

@kvlonge kvlonge commented Oct 3, 2026

Copy link
Copy Markdown
Contributor

Why

Model attachment (macro expansion, header columns, config, visible declarations, validation) ran for every model on every compile, about 25% of warm compile time (CHI-442, part of CHI-441).

Changes

  • Each model's attachment result is cached in the compile cache. The key covers the model file, applicable defaults and path defaults, vars, target (including target-level env values), adapter and dialect, the visible macro and declaration set, hook and audit-factory sources, custom adapter files under adapters/, and the installed code and native build identity.
  • Models whose own config, hooks or SQL read an environment variable or run.id are rebuilt every run.
  • Attachment diagnostics are stored and replayed on a hit; reference-name checks re-run on every hit, so adding a model only rebuilds that model. A macro or declaration edit rebuilds all models.
  • Docs: macros must be deterministic, and the docs say exactly what the reuse check covers.
  • Dense warm/edit guards assert attachment hit counts.

Verification

  • Same-machine medians, CPU s (base → head): dense 3k warm 10.70 → 9.90 and one-edit 12.58 → 11.78; 5k one-edit 19.85 → 18.72; ~1,400-model project warm 23.36 → 21.50. Output identical.
  • Invalidation E2E per input kind against --no-cache, each mutation-checked; run.id, env, diagnostic replay, model add/remove and macro edits.
  • One independent review plus a follow-up; make test, make check-ci.

@kvlonge
kvlonge enabled auto-merge (squash) October 3, 2026 05:12
Model attachment (config layering, declaration and macro expansion, hook
expansion, header columns and reference extraction) was recomputed for every
model on every compile. Each model's result is now stored in the compile
cache under a key covering the model file and path, its matched path
defaults, project defaults, vars, target, adapter and dialect, settings, the
shared macro and declaration sources, hook and audit-factory definitions,
project-local adapter sources, and the installed code identity. Editing any
macro or declaration re-attaches every model.

Models whose config, hooks or SQL read an environment variable or run.id are
always recomputed; environment values referenced by the target config are
part of the key instead. Diagnostics reported during attachment are stored and
replayed on a hit, and project-wide reference checks re-run so adding or
removing a model only attaches that model. compile_cache = false and
--no-cache disable the cache.

Macros are documented as deterministic, along with which project files the
reuse check covers.

Refs CHI-442
@kvlonge
kvlonge force-pushed the perf/chi-442-attachment-cache branch from 722c48c to 89eb40c Compare October 3, 2026 05:24
@kvlonge

kvlonge commented Oct 3, 2026

Copy link
Copy Markdown
Contributor Author

Shelving this PR. After #919 (speculative lint stop) and #922 (cold-compile GC pause) landed, the gain shrank to about 1–2% on the dense benchmarks and about 0.6 s on a ~1,400-model project, while cold compiles got ~1.7% slower and the fresh-process cache guard passes only narrowly. Most of the attachment time in the original profile came from GIL contention with the speculative lint, and unpickling cached attachment facts costs nearly as much as recomputing them. The branch stays available if attachment becomes a bottleneck again.

@kvlonge kvlonge closed this Oct 3, 2026
auto-merge was automatically disabled October 3, 2026 18:43

Pull request was closed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant