Skip to content

Optimize VecDeque clone and clone_from - #162991

Closed
fbernier wants to merge 2 commits into
rust-lang:mainfrom
fbernier:perf/vecdeque
Closed

fbernier wants to merge 2 commits into
rust-lang:mainfrom
fbernier:perf/vecdeque

Conversation

@fbernier

Copy link
Copy Markdown
Contributor

This PR adds two optimizations to VecDeque's clone and clone_from

The first restores allocation reuse for elements in clone_from. While looking through the commit history, I noticed that the rewrite in #102991 had removed the optimization introduced in the original clone_from. Instead of clearing the destination and cloning every element again, we now call clone_from on existing elements and clones any remaining source elements.

The only "trade-off" is that it can retain spare capacity in the destination elements for types such as String and Vec whereas the current implementation drops their allocations. This is Vec's current behavior though. Callers can use shrink_to_fit on individual elements if needed.

The second one adds a TrivialClone specialization for both clone and clone_from. It copies the source slices directly into the destination buffer instead of going through iterators.

ns/iteration on an AMD Ryzen 9 5950X:

Benchmark main This PR Change
clone_u64_contiguous 136.32 85.06 −37.6%
clone_u64_wrapped 134.67 85.02 −36.9%
clone_u64_small_wrapped 15.64 18.73 +19.8%
clone_string_contiguous 20,141.18 20,706.59 +2.8%
clone_from_u64_contiguous 112.64 58.04 −48.5%
clone_from_u64_wrapped 112.59 59.32 −47.3%
clone_from_string_contiguous 20,432.14 4,479.83 −78.1%
clone_from_string_wrapped 20,408.74 4,310.88 −78.9%

The clone_u64_small_wrapped weird result seems to be cause by either code-layout or weird glibc things. Running that benchmark alone by itself gives: 15.73 → 15.52 ns (−1.3%)

LLM disclosure: I used LLMs to review my implementation and to initially generate the tests and benchmarks which I then manually modified. I have personally reviewed these and I'm currently satisfied with them. The comments are my own except for the SAFETY comments which were corrected by an LLM.

Reuse existing element buffers and copy trivial elements in bulk.
@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 Sep 18, 2026
@rustbot

rustbot commented Sep 18, 2026

Copy link
Copy Markdown
Collaborator

r? @jhpratt

rustbot has assigned @jhpratt.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

Why was this reviewer chosen?

The reviewer was selected based on:

  • Owners of files modified in this PR: libs
  • libs expanded to 12 candidates
  • Random selection from 7 candidates

Comment on lines -584 to -588
assert_eq!(d.len(), 4);
let mut e = d.clone();
assert_eq!(e.len(), 4);
while !d.is_empty() {
assert_eq!(d.pop_back(), e.pop_back());

@asquared31415 asquared31415 Sep 18, 2026

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.

why did you modify this test?

View changes since the review

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

hhmm that's a good question. I think I was trying to match the Vec tests closer at some point but accidentally remove this. I don't really see a good reason to remove it so I guess I'll bring it back.

@hanna-kruppe

Copy link
Copy Markdown
Contributor

I'm going to close this PR as the LLM usage you disclosed is not in line with1 our LLM usage policy. You are welcome to open additional PRs as long as they follow our policy.

For additional information, see the guidelines in rustc-dev-guide.

Footnotes

  1. Our policy does not allow LLM-authored safety comments period, and for non-trivial code originally created by an LLM (including tests) it has additional requirements including arranging a reviewer beforehand and not being critical to soundness (this change seems very critical as it involves specialization and safety comments).

@rustbot rustbot removed the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Sep 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

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.

5 participants