[assembly-preparer] Compute the method-override map lazily.#26022
[assembly-preparer] Compute the method-override map lazily.#26022rolfbjarne wants to merge 1 commit into
Conversation
ComputeMethodOverridesStep used to eagerly scan every type in every assembly to build the map of which methods override which other methods (AnnotationStore.CollectOverrides), even though the map's only consumer - MarkNSObjectsStep, via GetOverrides - only does anything when trimming (its IsActiveFor requires the assembly's action to be AssemblyAction.Link). So when nothing is being trimmed the map was built (~0.75s for monotouch-test) but never queried. Compute the map lazily instead: CollectOverrides now just records the assemblies to scan, and the map is built the first time GetOverrides is actually called (memoized). When not trimming GetOverrides is never called, so the map is never built and the work is skipped entirely. Verified with monotouch-test on iOS (3675 tests, 0 failed) both with trimming (release|linksdk - the map is built lazily and consumed) and without (link None - the map is never built). Updated perf numbers: | Project | Runtime identifier | Link mode | PrepareAssemblies=false | PrepareAssemblies=true | Difference | | -------------- | ------------------ | --------- | ----------------------- | ---------------------- | ------------ | | monotouch-test | ios-arm64 | None | 00:02:18.82 | 00:02:21.22 | 00:00:02.39 | | monotouch-test | ios-arm64 | SdkOnly | 00:01:32.58 | 00:01:52.19 | 00:00:19.60 | | monotouch-test | iossimulator-arm64 | None | 00:01:48.13 | 00:01:45.84 | -00:00:02.28 | | monotouch-test | iossimulator-arm64 | SdkOnly | 00:01:18.06 | 00:01:26.86 | 00:00:08.79 | | MySimpleApp | ios-arm64 | None | 00:01:20.10 | 00:01:22.94 | 00:00:02.83 | | MySimpleApp | ios-arm64 | SdkOnly | 00:00:21.01 | 00:00:43.30 | 00:00:22.28 | | MySimpleApp | iossimulator-arm64 | None | 00:00:53.86 | 00:00:54.13 | 00:00:00.27 | | MySimpleApp | iossimulator-arm64 | SdkOnly | 00:00:19.46 | 00:00:29.42 | 00:00:09.96 | Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
Pull request overview
This PR optimizes the assembly-preparer/linker pipeline by avoiding an eager full-type scan to compute the method-override map when the map is never queried (notably in “no trimming” scenarios).
Changes:
- Made
AnnotationStore’s method-override map computation lazy and memoized, triggered on firstGetOverridesquery instead of duringCollectOverrides. - Updated
ComputeMethodOverridesStepto register assemblies for later override collection rather than performing the collection immediately.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| tools/assembly-preparer/Scaffolding/AnnotationStore.cs | Defers override-map construction until first query and caches the result. |
| tools/assembly-preparer/ComputeMethodOverridesStep.cs | Updates step description/intent to match the new lazy override-map behavior. |
✅ API diff for current PR / commitNET (empty diffs)✅ API diff vs stableNET (empty diffs)ℹ️ Generator diffGenerator Diff: vsdrops (html) vsdrops (raw diff) gist (raw diff) - Please review changes) Pipeline on Agent |
This comment has been minimized.
This comment has been minimized.
🚀 [CI Build #a2287c1] Test results 🚀Test results✅ All tests passed on VSTS: test results. 🎉 All 199 tests passed 🎉 Tests counts✅ assembly-processing: All 1 tests passed. Html Report (VSDrops) Download macOS tests✅ Tests on macOS Monterey (12): All 5 tests passed. Html Report (VSDrops) Download Linux Build VerificationPipeline on Agent |
ComputeMethodOverridesStep used to eagerly scan every type in every assembly to
build the map of which methods override which other methods
(AnnotationStore.CollectOverrides), even though the map's only consumer -
MarkNSObjectsStep, via GetOverrides - only does anything when trimming (its
IsActiveFor requires the assembly's action to be AssemblyAction.Link). So when
nothing is being trimmed the map was built (~0.75s for monotouch-test) but never
queried.
Compute the map lazily instead: CollectOverrides now just records the assemblies
to scan, and the map is built the first time GetOverrides is actually called
(memoized). When not trimming GetOverrides is never called, so the map is never
built and the work is skipped entirely.
Verified with monotouch-test on iOS (3675 tests, 0 failed) both with trimming
(release|linksdk - the map is built lazily and consumed) and without (link None -
the map is never built).
Updated perf numbers:
🤖 Pull request created by Copilot