mutants: speed up cargo-mutants runs #273
Labels
No labels
priority/P0
priority/P1
priority/P2
release/v0.1.0
status/blocked
status/planned
type/bug
type/design
type/test-gap
type/tracker
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
natsukium/felis#273
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Context
cargo mutants --listcurrently reports 5161 mutants under the existing scope (crates/felis-grid,crates/felis-vt,crates/felis-protocol). At that count, full runs are dominated by per-mutant incremental rebuild + test time: the last baseline took ~23s to build with an auto-set test timeout of 58s (seemutants.out/debug.log)..cargo/mutants.tomlis already in good shape:test_tool = "nextest",examine_globsrestricted to the boundary-logic crates, and committed prost codegen pluscfg(kani)dead code excluded. No linker override and no[profile.mutants]exist yet.Assessment of the commonly cited tweaks
Evaluated against this cargo-mutants performance post:
dev/flake-module.nix, not ad-hocRUSTFLAGS.[profile.mutants](inherits = "test", debug info off): helps, but inert on its own. Just adding the profile toCargo.tomlchanges nothing until cargo-mutants selects it (--profile mutants/ configprofile). First run after adding it pays one full rebuild into a separate target dir.-j:-j2is too low here. That starting value is generic advice; on a 12-core / 62 GB machine we can go higher while watching memory (outer mutants-jmultiplies with nextest's inner parallelism).TMPDIR: lowest priority, do not do first./tmphere is disk-backed while/dev/shm(32G tmpfs) exists, so tmpfs scratch is possible — but it competes for memory with parallel builds. Only worth it if I/O proves to be the bottleneck.Bigger wins than any single build tweak
--in-difffor PRs,--shard n/mfor CI and local trials,-F/--file,-p,--iterate.--timeout-multiplier/minimum-test-timeoutand#[mutants::skip]for hang-prone fns.Proposed steps
cargo mutants --shard 0/8for baseline build time and per-mutant average.[profile.mutants]+ select it via--profile mutants/config; compare on the same shard.-jwhile watching memory.--in-difffor PRs and--shardfor full runs as the standard workflow.Acceptance
.cargo/mutants.toml/Cargo.toml/ Nix config as appropriate (no ad-hoc local-only flags).just mutants.Measured and landed the effective tweaks in #274 (branch
mutants-speed). All numbers below are same-scopebefore/after on the 12-core / 62 GB dev machine.
1.
[profile.mutants](inherits = "test",debug = 0) — helps, landedSelected via
profile = "mutants"in.cargo/mutants.toml(declaring it inCargo.tomlalone is inert).felis-gridtouch +nextest --no-run): 3.05s -> 2.19s (~28%)2.
-j—-j4is the knee, landed as thejust mutantsdefault18-mutant mixed set (
-F 'PartialEq', 7 missed / 11 caught),--profile mutants:(On a 5-mutant all-caught micro-set -j1 beats -j4, 48s vs 64s — outer parallelism only pays once the run is
large enough to amortize contention, which every real sweep is.)
jobscannot be pinned in.cargo/mutants.toml— the config schema rejects it (unknown field 'jobs') — sothe default lives in the
just mutants*recipes viaCARGO_MUTANTS_JOBS="${CARGO_MUTANTS_JOBS:-4}", stilloverridable.
3. mold via the Nix dev shell — helps on top, landed
Warm single-crate rebuild under the mutants profile: 2.11s (BFD) -> 1.59s (mold), ~25% off the
link-dominated remainder; combined with the profile, 3.05s -> 1.59s (~48%). Verified end-to-end through a
mutants scratch run (env propagates to the child cargo invocations). Wired as Linux-only
RUSTFLAGSin thedev shell's
shellHook, not.cargo/config.toml, so non-shell and macOS builds keep the default linker.4. Standard workflow — landed
just mutants-pr(mutants touched bybase...HEAD, defaultorigin/main)just mutants-shard 0/8(every shard), i.e.--shardfor trials as proposed--in-difftakes a unified diff file path;-Fremains the narrowing filter(
--fileunions withexamine_globsand widens instead)Deliberately not done
TMPDIR: the reflinked scratch copy is ~51 GB / ~93k files, larger than the 32 GB/dev/shmtmpfs — it does not fit. Reflink copy on btrfs takes ~10s, not the bottleneck.
timeout problem.
--copy-target/--gitignoretuning: the copiedtarget/dir warms the baseline build (18s vs 38scold), so skipping the copy to save ~10s would lose more than it gains.
--test-workspace false: kept at default per the skill's note — narrowing by workspace dropscross-crate coverage and reports false survivors.
Acceptance
-Fsets; a full 0/8 shard was not re-runend-to-end since each configuration point costs ~30 min — the
-Fsets isolate each variable)..cargo/mutants.toml/Cargo.toml/ Nix config, no ad-hoc local flags.just mutants/just mutants-pr/just mutants-shard.