Skip to content

perf(common): index artifact bytecode matching - #16080

Open
mattsse wants to merge 2 commits into
masterfrom
mattsse/perf-artifact-bytecode-matcher
Open

perf(common): index artifact bytecode matching#16080
mattsse wants to merge 2 commits into
masterfrom
mattsse/perf-artifact-bytecode-matcher

Conversation

@mattsse

@mattsse mattsse commented Aug 8, 2026

Copy link
Copy Markdown
Member

ContractsByArtifact now keeps exact deployed-bytecode candidates in ordered code-length buckets and lazily prepares each candidate's ignored ranges and unlinked-bytecode representation. The buckets are populated in the existing BTreeMap order, the first fully linked artifact retains a direct fast path, and query metadata is parsed once, preserving the existing earliest-exact and last-partial selection behavior across metadata, immutables, link references, placeholders, and library call protection. This complements #16069's linker path index; it does not change linker resolution.

Candidates store only the artifact id, the match bytecode, and the ignored ranges; a hit resolves back through the artifact map instead of retaining a clone of the contract data, so building the index does not duplicate ABIs or bytecode. That lookup costs roughly 0.3 µs per exact or partial hit and shows up in the small-set middle/last rows below, while misses — which don't touch the map at all — and larger artifact sets stay well ahead of the linear scan.

Results

Criterion 0.7 steady-state medians against master (7c271517a3), same machine and run, using identical 128-length-bucket artifact sets:

Artifacts / query Candidates checked master this PR delta
100 / first 1 → 1 24.034 ns 17.087 ns -28.9%
100 / middle 51 → 1 89.220 ns 308.76 ns +246.1%
100 / last 100 → 1 148.27 ns 481.45 ns +224.7%
100 / miss 100 → 0 123.53 ns 12.380 ns -90.0%
1,000 / first 1 → 1 40.046 ns 17.486 ns -56.3%
1,000 / middle 501 → 4 1.3282 µs 690.39 ns -48.0%
1,000 / last 1,000 → 8 1.9005 µs 809.66 ns -57.4%
1,000 / miss 1,000 → 0 1.3922 µs 14.684 ns -98.9%
5,000 / first 1 → 1 32.689 ns 17.730 ns -45.8%
5,000 / middle 2,501 → 20 3.9932 µs 749.63 ns -81.2%
5,000 / last 5,000 → 40 7.9030 µs 1.1539 µs -85.4%
5,000 / miss 5,000 → 0 7.0576 µs 14.700 ns -99.8%

The + rows are exact hits in small artifact sets where the final id lookup dominates; the callers (cheatcodes, verify) pay it once per matched query and mostly issue misses against foreign code, which is where the old scan was spending its time.

This PR was written with Codex, including the implementation, tests, benchmarks, and pull request text.

Bucket exact deployed-bytecode candidates by length and cache normalized match plans while retaining artifact selection order.

At 5,000 artifacts, Criterion steady-state middle/last/miss lookups improve from 3.815/7.935/7.216 us to 124/214/15.9 ns.
@github-actions

github-actions Bot commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

✅ Changelog found

The deterministic check will validate the changed entry.

@figtracer

Copy link
Copy Markdown
Member

i think we don't need these huge changes for average 100ns save

@foundry-rs foundry-rs deleted a comment from stevencartavia Aug 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

2 participants