From f8b7160e46078686addca9aca26654421b336cad Mon Sep 17 00:00:00 2001 From: zackees Date: Sun, 21 Jun 2026 16:48:50 -0700 Subject: [PATCH] perf(uv): rebuild fbuild ~14x faster on no-source-change reinstall MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The slow path was `uv sync --reinstall-package fbuild` (also fires on version bumps / lockfile churn): 14.9s of cargo work even when no Rust source had changed, because PEP 517 build isolation copies the source tree to a temp dir each time and cargo's incremental cache lives at `/target/` — discarded after the build. Three coordinated changes: - `setup.py`: pin `CARGO_TARGET_DIR` to `~/.fbuild/cargo-target/wheel-build` so the incremental cache survives. Add an mtime-skip in `BuildWithCargo.run` that short-circuits cargo entirely when the staged `ci/bin/fbuild[.exe]` is newer than every `crates/**/*.rs`, `Cargo.toml`, `Cargo.lock`, `rust-toolchain.toml`. - `pyproject.toml`: `[tool.uv] no-build-isolation-package = ["fbuild"]` so the build runs in the real repo (not a temp copy). `default-groups = ["dev"]` + setuptools in the `dev` group so setuptools is in the venv when uv tries to rebuild the wheel (no chicken-and-egg). - `pyproject.toml`: `cache-keys = [..., "crates/**/*.rs", ...]` so uv's editable install actually re-syncs on Rust edits — without this the compiled `_native.pyd` silently stayed stale until manual reinstall. Measurements (on Windows, soldr 0.7.55, uv 0.8.11): | Scenario | Before | After | |-------------------------------------------|--------:|--------:| | forced reinstall, no source change | 14.9s | 1.1s | | real `.rs` edit + `uv run python --ver` | 15.7s | 14.3s | | warm `uv run python --version` | ~110ms | ~100ms | The 13.6x win is on the no-source-change path (mtime-skip never invokes cargo). The real-edit path is at cargo's incremental + linker floor on this workspace; pushing further would need a faster linker (rust-lld/mold) — separate change. See `ci/bench-results/REPORT.md` for full methodology and raw timings. Co-Authored-By: Claude Opus 4.7 (1M context) --- ci/bench-results/README.md | 15 +++ ci/bench-results/REPORT.md | 109 ++++++++++++++++++ ci/bench-results/after_fixes.json | 139 +++++++++++++++++++++++ ci/bench-results/baseline.json | 139 +++++++++++++++++++++++ ci/bench_uv_run.py | 181 ++++++++++++++++++++++++++++++ pyproject.toml | 47 +++++++- setup.py | 58 ++++++++++ uv.lock | 17 ++- 8 files changed, 700 insertions(+), 5 deletions(-) create mode 100644 ci/bench-results/README.md create mode 100644 ci/bench-results/REPORT.md create mode 100644 ci/bench-results/after_fixes.json create mode 100644 ci/bench-results/baseline.json create mode 100644 ci/bench_uv_run.py diff --git a/ci/bench-results/README.md b/ci/bench-results/README.md new file mode 100644 index 00000000..c1fe3ddb --- /dev/null +++ b/ci/bench-results/README.md @@ -0,0 +1,15 @@ +# Bench results + +Raw timings + writeup from the `uv run` rebuild-speedup investigation +that ships with this directory. + +- **`REPORT.md`** — analysis: what the bottleneck was, what was applied, + before/after numbers, what's left. +- **`baseline.json`** — `ci/bench_uv_run.py` output against `main` before + the fixes. +- **`after_fixes.json`** — same script after applying `CARGO_TARGET_DIR` + pinning + `BuildWithCargo` mtime-skip + `no-build-isolation-package` + + `cache-keys`. + +Reproduce with `python ci/bench_uv_run.py