Skip to content

Optimize BTreeMap::append() using CursorMut#153107

Open
asder8215 wants to merge 1 commit intorust-lang:mainfrom
asder8215:btreemap_append_optimized
Open

Optimize BTreeMap::append() using CursorMut#153107
asder8215 wants to merge 1 commit intorust-lang:mainfrom
asder8215:btreemap_append_optimized

Conversation

@asder8215
Copy link
Contributor

@asder8215 asder8215 commented Feb 25, 2026

Since BTreeMap::merge uses CursorMut to avoid reconstructing the map from scratch and instead inserting other BTreeMap at the right places or overwriting the value in self BTreeMap on conflict, we might as well do the same for BTreeMap::append. This also means that some of the code in append.rs can be removed; bulk_push() however is used by bulk_build_from_sorted_iterator(), which is used by the From/FromIterator trait impl on BTreeMap. Feels like we should rename the file or place the bulk_push() in an existing file.

The same additional optimization consideration that BTreeMap::merge has is also applied to BTreeMap::append.

r? @Mark-Simulacrum since Mark has seen the BTreeMap::merge code already (only diff is the Ordering::Equal case and now one of the test assertions on a panic case has the correct value now).

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-libs Relevant to the library team, which will review and decide on the PR/issue. labels Feb 25, 2026
@asder8215
Copy link
Contributor Author

asder8215 commented Feb 25, 2026

I'd be curious to see if this shows any noticeable performance difference with the current implementation of BTreeMap::append

&mut self.length,
(*self.alloc).clone(),
)
// Because `other` takes a &mut Self, in order for us to own
Copy link
Member

Choose a reason for hiding this comment

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

Do we think this is worth it vs. calling merge with the right conflict function?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I guess it's a bit redundant with how merge does everything that append does with the added benefit on what you want the value to be on conflicting keys. I'm not sure why one would prefer having less flexibility deciding what the resultant value of conflicting keys should be with BTreeMap::append over using BTreeMap::merge.

I think I wanted the code internally for BTreeMap::append() to be consistent with BTreeMap::merge() since we can remove some code that only BTreeMap::append uses if we have BTreeMap::merge() and BTreeMap::append() sharing the same CursorMut functions. Moreover, I think I just found it unnecessary how the BTreeMap in BTreeMap::append constructs it from scratch rather than just placing the elements of other BTreeMap into the appropriate spots of self BTreeMap.

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

Labels

S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-libs Relevant to the library team, which will review and decide on the PR/issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants