From d9b732ad25f285b701c2d9097840403cddc48d0c Mon Sep 17 00:00:00 2001 From: zackees Date: Sun, 21 Jun 2026 22:58:56 -0700 Subject: [PATCH] perf(build): rust-lld linker on Windows + opt-3 deps in dev profile (#2 items 2+3) Two cargo-config knobs ported from FastLED/fbuild#744 that together collapse the local Rust-edit iteration loop without any release-build regression: 1. `[profile.dev.package."*"] opt-level = 3` in Cargo.toml. Cargo compiles each upstream crate once and caches the opt-level-3 artifact, so runtime hot paths (pyo3, serde, etc.) stay at release-grade perf while first-party crates compile unoptimized for fast iteration. This is what makes "default to dev for local iteration" safe for downstream consumers; without it, defaulting to dev silently regresses runtime perf. 2. `[target.{x86_64,aarch64}-pc-windows-msvc] linker = "rust-lld.exe"` in .cargo/config.toml. rust-lld ships with the Rust toolchain (no extra install) and links 2-5x faster than MSVC's link.exe on link-heavy rebuilds. Escape hatch: RUSTFLAGS="-C linker=link.exe" for the rare case rust-lld trips on a foreign object file. POSIX builds keep their platform default linker. Verified `cargo build -p template-cli` succeeds with both changes in place. fbuild measured ~5x faster Rust-edit rebuild from this pair of changes on its workspace; will be smaller here because the template's dep tree is tiny, but the proportional win scales with downstream consumers as they grow. Refs zackees/template-python-rust-cmd#2 (items 2 + 3). Co-Authored-By: Claude Opus 4.7 --- .cargo/config.toml | 16 ++++++++++++++++ Cargo.toml | 11 +++++++++++ 2 files changed, 27 insertions(+) diff --git a/.cargo/config.toml b/.cargo/config.toml index fcb07c1..7210779 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -10,3 +10,19 @@ incremental = true [profile.test] debug = "line-tables-only" incremental = false + +# rust-lld ships with the Rust toolchain (no extra install) and links +# 2-5x faster than MSVC's link.exe on link-heavy rebuilds. The dev +# profile already lives in the hot iteration loop; cutting the link +# step is the biggest single win there. Set per Windows target so +# unix/macos builds keep their platform default linker. +# +# Escape hatch if rust-lld trips on a foreign object file: +# RUSTFLAGS="-C linker=link.exe" cargo build +# +# See fbuild#744 and zackees/template-python-rust-cmd#2. +[target.x86_64-pc-windows-msvc] +linker = "rust-lld.exe" + +[target.aarch64-pc-windows-msvc] +linker = "rust-lld.exe" diff --git a/Cargo.toml b/Cargo.toml index 50543cb..f78d54b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,3 +17,14 @@ homepage = "https://github.com/example/template-python-rust-cmd" [workspace.dependencies] anyhow = "1" pyo3 = { version = "0.23", features = ["extension-module"] } + +# Keep third-party crates release-grade even in the dev profile. +# `cargo build` (no --release) compiles first-party crates unoptimized +# for fast iteration; third-party deps (pyo3, serde, etc.) are compiled +# once and cached at opt-level 3 so the runtime hot path stays as fast +# as a release build. This is what makes "default to dev for local +# iteration" safe — see fbuild#744 (~5x faster Rust-edit rebuild on +# fbuild's workspace) and zackees/template-python-rust-cmd#2. +[profile.dev.package."*"] +opt-level = 3 +debug = false