Skip to content

Remove unnecessary context allocation - #952

Open
vinistock wants to merge 1 commit into
mainfrom
vs_remove_unnecessary_context_allocation
Open

Remove unnecessary context allocation#952
vinistock wants to merge 1 commit into
mainfrom
vs_remove_unnecessary_context_allocation

Conversation

@vinistock

Copy link
Copy Markdown
Member

Currently, we are allocating a new LinearizationContext each time for ancestors_of. This is completely unnecessary because the linearization recursion already cleans up the context object.

We can simply reuse the same object stored in the Resolver, avoid the allocation entirely and remove ancestors_of while we're at it. This provides a 12% speed up for resolution, bringing us to ~11s.

@vinistock vinistock self-assigned this Jul 23, 2026
@vinistock
vinistock requested a review from a team as a code owner July 23, 2026 14:09
@vinistock vinistock added the enhancement New feature or request label Jul 23, 2026
Comment thread rust/rubydex/src/resolution.rs Outdated
@vinistock
vinistock force-pushed the vs_avoid_duplicate_namespace_lookup branch from 5e999d4 to fed5ec3 Compare July 29, 2026 22:55
@vinistock
vinistock force-pushed the vs_remove_unnecessary_context_allocation branch from 78d8c0f to 3bd9ea1 Compare July 29, 2026 23:48
@vinistock
vinistock requested a review from Morriar July 29, 2026 23:49
@vinistock
vinistock force-pushed the vs_avoid_duplicate_namespace_lookup branch from fed5ec3 to f06bd59 Compare July 31, 2026 19:28
@vinistock
vinistock force-pushed the vs_remove_unnecessary_context_allocation branch from 3bd9ea1 to 8fac711 Compare July 31, 2026 19:29
Base automatically changed from vs_avoid_duplicate_namespace_lookup to main July 31, 2026 19:40
@soutaro

soutaro commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

I find the lifecycle of LinearizationContext harder to follow when it is mutated implicitly through Resolver. Could we keep the reuse as an implementation detail of ancestors_of, while making the active traversal state explicit?

For example, ancestors_of could take the reusable context out, initialize it, pass it explicitly through the traversal, validate that it has been cleaned up, and then put it back:

let mut context = self
    .reusable_linearization_context
    .take()
    .expect("ancestor linearization must not be re-entered");

context.begin();
let result = self.linearize_ancestors(declaration_id, &mut context);
debug_assert!(context.is_idle());

self.reusable_linearization_context = Some(context);
result

This retains the allocation benefit, while making the context’s lifetime and ownership at a traversal call site easier to reason about. Using Option would also make accidental re-entry fail explicitly, instead of silently taking a new default context.


By the way, a 12% speedup from allocation reduction alone seems a little surprising. What is actually driving the improvement?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants