8000 perf(check): read only the parts of artifact files the checkers need by bryan-minimal · Pull Request #2235 · gominimal/minimal · GitHub
[go: up one dir, main page]

Skip to content

perf(check): read only the parts of artifact files the checkers need - #2235

Merged
bryan-minimal merged 3 commits into
mainfrom
perf/check-mmap-artifacts
Oct 22, 2026
Merged

bryan-minimal merged 3 commits into
mainfrom
perf/check-mmap-artifacts

Conversation

@bryan-minimal
@bryan-minimal bryan-minimal commented Oct 16, 2026 •
Copy link
Copy Markdown
Member

OutputTypesValid, MissingRuntimeDeps and CheckCache::lib_symbols read every artifact file whole (std::fs::read) to parse its ELF header, imports and dynamic symbols. A full-catalog check sweep therefore reads every byte of every output on both arches, though the parsers touch a few pages per file. On a host whose page cache is cold, the sweep becomes disk-bound.

This maps the file read-only instead (map_output → memmap2::Mmap, empty files special-cased since a zero-length map is refused) and advises MADV_RANDOM, because default readahead pulls a window behind every fault. object::File::parse takes the same &[u8], so no parsing code changes.

Measured

A standalone benchmark doing what these checkers do to each file (open, object::File::parse, walk imports and dynamic symbols): 261,820 files / 39.2 GiB of real built/ artifacts, 20 threads (the check semaphore), page cache evicted per file with posix_fadvise(DONTNEED) for the cold runs. Two runs each:

variant cold wall cold disk read warm wall
read whole file (main) 112–123 s 19.1 GiB 4.0–5.8 s
mmap 46–50 s 6.25 GiB 2.3 s
mmap + MADV_RANDOM (this PR) 25.5–26.7 s 1.78 GiB 3.0 s

Identical results in every run (5,592 ELF files parsed, 545,713 imports).

Why it matters

gominimal/build-servers#210: merge-queue runs sweep the full catalog (16,560 objects). Over the last 7 days they took 83 s median and up to 474 s, and the slow ones are the first run after an on-demand VM boots. In Cloud Trace, the same 1,106 package checks averaged 7.9 s cold vs 2.0 s warm, with over 90% of span time idle: blocking whole-file reads on async workers stalled every other check on those workers.

check crate: fmt, clippy -D warnings, 17 tests pass (Linux).

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • Improved compatibility when checking binaries and libraries, including large files.
    • Script checks now recognize interpreter paths when a script’s shebang line has no trailing newline.
    • Invalid or unreadable script headers are handled without being mistaken for valid interpreter paths.

The output checkers and lib_symbols read every artifact file whole to
parse its ELF header, imports and dynamic symbols, so a full-catalog
sweep read every byte of every output. Map them read-only with
MADV_RANDOM: on a cold sweep of 39 GiB of artifacts, 123 s / 19 GiB
from disk becomes 26 s / 1.8 GiB, with identical results
(build-servers#210).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@bryan-minimal
bryan-minimal requested a review from a team as a code owner October 16, 2026 17:46
@coderabbitai
coderabbitai Bot commented Oct 16, 2026 •
Copy link
Copy Markdown
Contributor

Review in Change Stack →

Important

Review skipped

Review was skipped due to path filters

⛔ Files ignored due to path filters: 1
  • Cargo.lock is excluded by !**/*.lock

CodeRabbit blocks several paths by default. You can override this behavior by explicitly including those paths in the path filters. For example, including **/dist/** will override the default block on the dist directory, by removing the pattern from both the lists.

⚙️ Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: CHILL
  • Plan: Essentials
  • Run ID: 1a957d23-b917-4136-9ad1-024d21fc5a65

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: CHILL
  • Plan: Essentials
  • Run ID: dd055093-c58a-4586-9d49-31480cf3257b
📥 Commits

Reviewing files that changed from the base of the PR and between e1ca8b7 and f15fa4f.

⛔ Files ignored due to path filters: 1
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing: 3
  • crates/check/Cargo.toml
  • crates/check/src/lib.rs
  • crates/check/src/outputs.rs

Included review availability: This review used your included allowance. 0 included reviews remain after this review. Your included PR review attempts over the past 7 days set your current allowance at 5 reviews per hour.

📝 Walkthrough

The check crate now reads library and output artifacts through a cached reader instead of loading entire files. Script detection and interpreter extraction use read-cache helpers, with tests for truncated artifacts and shebang input.

Changes: Check output reading

Layer / File(s) Summary
Add cached library reading
crates/check/Cargo.toml, crates/check/src/lib.rs
Adds open_output and uses it to parse libraries and the glibc fallback. On Linux, the helper requests random-access file advice. A Linux test checks parsing after truncating an opened artifact.
Read and validate output artifacts
crates/check/src/outputs.rs
Output validation and runtime dependency checks parse cached readers. Script detection checks for #!, and interpreter extraction reads through the first newline. Tests cover cached shebang input, scripts without a newline, and non-script data.

Priority: ⬇️ Low

Estimated code review effort: 3 (Moderate) | ~20 minutes

Change: Refactor

Suggested reviewers: 0chroma, twitchyliquid64

Merge Risk: ⚪ Minimal · up to f15fa

The artifact-reading change has no identified merge-blocking issue; merge after normal checks.

Pre-merge checks: Passed 4 · Failed 1

Failed Failed checks: 1 warning

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 70.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 10 functions across 2 files. (1 skipped: … Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks: 4 passed
Check name Status Explanation
Title check Passed The title clearly and concisely describes the main performance change. It follows the repository's Conventional Commit format.
Description check Passed The description explains the change, motivation, measured results, impact, and testing status. It omits the template Checklist and does not include command output, but it is otherwise mostly complete.
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Full details: Docstring Coverage

Explanation

Docstring coverage is 70.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 10 functions across 2 files. (1 skipped: 1 unsupported.)

Resolution

Write docstrings for the functions missing them to satisfy the coverage threshold.

✨ Finishing Touches: 💡 1
📝 Generate docstrings: 💡
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

A rabbit checks each file with care
No whole-file heap is needed there
A shebang marks the script’s first line
The cached reader keeps its place in time
Then hops away, its checks in line

Comment @coderabbitai help to get the list of available commands.

@minimal-foundry
minimal-foundry Bot commented Oct 16, 2026 •
Copy link
Copy Markdown
Contributor

Approved: no findings at d9f0aa3ed742.

Nothing to do.

Clobber: none seen.

@minimal-foundry minimal-foundry Bot left a comment
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

correctness

minimal-review — approved

Verdict APPROVE — No findings.

security

minimal-review — advisory review

Verdict COMMENT — 1 finding, 1 inline.

supply-chain

minimal-review — approved

Verdict APPROVE — No findings.

Panel: 3 of 3 personas ran (correctness, security, supply-chain).

Comment thread crates/check/src/lib.rs Resolved
@minimal-foundry minimal-foundry Bot left a comment
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

correctness

minimal-review — advisory review

Verdict COMMENT — 1 finding, 1 inline.

security

minimal-review — approved

Verdict APPROVE — No findings.

supply-chain

minimal-review — approved

Verdict APPROVE — No findings.

Panel: 3 of 3 personas ran (correctness, security, supply-chain).

Comment thread crates/check/src/lib.rs Resolved
@bryan-minimal bryan-minimal changed the title perf(check): map artifact files instead of reading them whole perf(check): read only the parts of artifact files the checkers need Oct 19, 2026
@minimal-foundry minimal-foundry Bot left a comment
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minimal-review — approval withheld

Verdict COMMENT — APPROVE withheld: 1 unresolved thread — minimal-foundry[bot] crates/check/src/lib.rs. No findings.

Panel: 3 of 3 personas ran (correctness, security, supply-chain).

@minimal-foundry minimal-foundry Bot left a comment
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minimal-review — approved

Verdict APPROVE — every review thread is resolved; @bryan-minimal closed the last one. The review of f15fa4f51468 withheld this approval on the threads open then.

@minimal-foundry minimal-foundry Bot added the review:approved minimal-review approved the current head label Oct 19, 2026
bryan-minimal and others added 2 commits October 22, 2026 10:58
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A mapped artifact turned a file truncated under the check into SIGBUS for
the whole process. These files are hardlinked into build sandboxes, and a
build writing through the link (cp or > onto it) truncates the shared
inode, so "nothing rewrites them in place" was assumed, not enforced.
object::read::ReadCache reads only the ranges the parsers ask for, so a
truncated file is one short read and one parse error. With
POSIX_FADV_RANDOM it keeps the cold-sweep win: 24-27 s / 2.0 GiB against
mmap's 25-26 s / 1.8 GiB on 39 GiB of artifacts, and 0.6 s warm against
3 s. No unsafe; memmap2 leaves the check crate.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@bryan-minimal
bryan-minimal force-pushed the perf/check-mmap-artifacts branch from f15fa4f to d9f0aa3 Compare October 22, 2026 18:05
@minimal-foundry minimal-foundry Bot left a comment
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minimal-review — approved

Verdict APPROVE — No findings.

Panel: 3 of 3 personas ran (correctness, security, supply-chain).

@bryan-minimal
bryan-minimal added this pull request to the merge queue Oct 22, 2026
Merged via the queue into main with commit 4be6709 Oct 22, 2026
36 checks passed
@bryan-minimal
bryan-minimal deleted the perf/check-mmap-artifacts branch October 22, 2026 19:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

review:approved minimal-review approved the current head

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

0