Measurement
- In the
coverage job of merge_group run 37828932401, the step "Run tests with coverage" takes 15.8 min.
- The instrumented compile plus tests ends at about 13.3 min.
- It then runs
cargo llvm-cov report --lcov (78 s), followed by cargo llvm-cov report --summary-only (74 s).
- Across 7 days,
coverage takes p50 12.5 min and p90 15.1 min (n=950 jobs).
- Since 2026-10-08 02:16Z, about 427 CI runs per day include
coverage:
- 287 pull_request
- 105 merge_group
- 35 push
Where the time goes
.github/workflows/ci.yml, at about lines 536–539:
cargo llvm-cov --workspace --no-fail-fast ...
cargo llvm-cov report --lcov --output-path coverage-host.lcov
cargo llvm-cov report --summary-only | tee coverage-summary.txt
Each report call merges the .profraw files with llvm-profdata and walks every instrumented object. The two calls do the same work.
Root cause
The summary is produced by a second full report pass. It is not derived from the lcov output that was just written.
Proposed fix
Pick one of these:
- (a) Run both
report invocations concurrently, using & and wait. This cuts wall time by about 75 s but saves no CPU.
- (b) Preferred: emit lcov once and compute the per-file summary table from
coverage-host.lcov. The LF/LH/BRF/BRH/FNF/FNH records hold the line, branch and function totals. A small Python helper in scripts/ can render the same fenced table the next step prints.
Keep coverage-summary.txt in the same format so that coverage-merge and the step summary don't change.
Expected saving
- With (b): about 1.25 min of job time per run, which is about 530 Linux job-min per day.
coverage wall time drops by about 1.3 min.
- Critical path: about 0.
coverage finishes before the Gradle e2e legs, and in the last 37 green merge_group runs it was never the job that gated ci-ok.
Coverage and risk
- Test execution is unchanged; only the reporting changes.
- Risk: summary numbers could drift from llvm-cov's own summary. Diff the two outputs on one run before switching.
- The required checks
ci-ok and clippy are unchanged.
Effort
S
ROI
ROI = weighted saving × confidence / effort.
- Weighted saving: 0.53k Linux job-min per day.
- Confidence: 0.8. Effort: S, which counts as 1.
- ROI = 0.53 × 0.8 / 1 = 0.42
Measurement
coveragejob of merge_group run 37828932401, the step "Run tests with coverage" takes 15.8 min.cargo llvm-cov report --lcov(78 s), followed bycargo llvm-cov report --summary-only(74 s).coveragetakes p50 12.5 min and p90 15.1 min (n=950 jobs).coverage:Where the time goes
.github/workflows/ci.yml, at about lines 536–539:Each
reportcall merges the.profrawfiles withllvm-profdataand walks every instrumented object. The two calls do the same work.Root cause
The summary is produced by a second full report pass. It is not derived from the lcov output that was just written.
Proposed fix
Pick one of these:
reportinvocations concurrently, using&andwait. This cuts wall time by about 75 s but saves no CPU.coverage-host.lcov. TheLF/LH/BRF/BRH/FNF/FNHrecords hold the line, branch and function totals. A small Python helper inscripts/can render the same fenced table the next step prints.Keep
coverage-summary.txtin the same format so thatcoverage-mergeand the step summary don't change.Expected saving
coveragewall time drops by about 1.3 min.coveragefinishes before the Gradle e2e legs, and in the last 37 green merge_group runs it was never the job that gatedci-ok.Coverage and risk
ci-okandclippyare unchanged.Effort
S
ROI
ROI = weighted saving × confidence / effort.