Skip to content

perf(compile): faster cold compiles - #922

Merged
kvlonge merged 4 commits into
mainfrom
perf/chi-441-cold-compile
Oct 3, 2026
Merged

kvlonge merged 4 commits into
mainfrom
perf/chi-441-cold-compile

Conversation

@kvlonge

@kvlonge kvlonge commented Oct 3, 2026

Copy link
Copy Markdown
Contributor

Why

Cold compiles spent seconds re-reading and rewriting artifacts from a system temp directory, scanning every SQL test for comments and quotes, and running cyclic garbage collection, which alone took 18–25 s per 10k-model compile (CHI-441 phase 2, part of CHI-447/448).

Changes

  • --no-cache artifacts are staged under target/ and published by rename. The owner lock is taken before the staging dir exists; cleanup of leftovers from killed runs holds the lock throughout; publish verifies its staging tree before moving or deleting anything. Cross-device destinations fall back to an atomic copy.
  • SQL-test planning scans for comments and quoted text only when a marker needs it.
  • sqb compile pauses cyclic GC for the command and restores it afterwards.
  • One shared line-position helper replaces three copies.

Verification

  • Same-machine medians, CPU s (base → head): dense 3k 38.1 → 33.2, 5k 65.0 → 54.2, 10k 118.2 → 98.3, fresh 3k 14.6 → 12.8, ~1,400-model project 18.0 → 16.5. Peak RSS +3–4% (10k: 2.75 GB). Compile JSON and target/compiled byte-identical.
  • Tests for cross-device publish, staging interleaving and tampering, GC restore and marker scanning.
  • One independent review plus a follow-up; make test, make check-ci.

…ying

Background artifact preparation wrote every compiled file to a system temp
directory and the write phase then walked, read and rewrote each one into
target/. Stage beside target/ on the same filesystem instead, move the whole
tree into place when target/compiled is absent, and otherwise rename new files
and rewrite only changed ones, keeping the unchanged-file and stale-file
semantics.

Each staging directory is claimed by locking a sibling owner lock before the
directory exists, held for the whole compile. At the start of a compile,
staging directories are removed only while this compile holds their owner lock
for the entire removal; cleanup stops and logs instead of continuing after a
failed removal. Publication verifies the owner marker and the staged file set
before moving anything or deleting stale files, and fails the compile rather
than deleting valid artifacts if staging changed. New files that cannot be
renamed across filesystems (EXDEV, for example target/compiled symlinked to
another mount) are copied through a sibling temporary file and replaced
atomically.
…eds them

SQL-test planning rescanned each model's comments and quoted text once per
marker kind even when that kind never occurs, and checked every match against
every range. Scan lazily on the first candidate match, share one scan across
the unresolved-reference checks, and look ranges up by binary search.
Rendered test SQL is byte-identical.
…mand

A cold compile keeps millions of objects alive until it finishes, so every
full cyclic collection rescans that heap without freeing it (about 2-4 s of
GIL-held time on the 3,000- and 5,000-model dense benchmarks). Disable the
cyclic collector for the duration of the compile command and restore the
previous state afterwards; reference counting still frees acyclic garbage.
…covery

Native SQL lint, header lint and model discovery each kept a private copy of
the line-start table and offset-to-position mapping; the native SQL lint copy
scanned character by character in Python. Give discovery the single owner
using str.find and reuse it from both lint modules. Positions are unchanged.
@kvlonge
kvlonge enabled auto-merge (squash) October 3, 2026 07:41
@kvlonge
kvlonge merged commit 9311dda into main Oct 3, 2026
34 checks passed
@kvlonge
kvlonge deleted the perf/chi-441-cold-compile branch October 3, 2026 08:02
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