Skip to content

Add push_reserved() and optimize extend() to avoid unnecessary capacity checks#76

Closed
SOF3 wants to merge 1 commit intomozilla:mainfrom
SOF3:push-reserved
Closed

Add push_reserved() and optimize extend() to avoid unnecessary capacity checks#76
SOF3 wants to merge 1 commit intomozilla:mainfrom
SOF3:push-reserved

Conversation

@SOF3
Copy link
Copy Markdown
Contributor

@SOF3 SOF3 commented Oct 11, 2025

Implements the optimization as proposed in #58, renaming the proposed method from push_unchecked to push_reserved for clarity.

Benchmarks

Benchmarks of <ThinVec as From<[u16; N]>>::from(array) show the following improvements.

Environment: Linux 6.16.7-arch1-1, rustc 1.91.0-beta.4, x86_64-unknown-linux-gnu, Intel(R) Core(TM) i7-10510U CPU @ 1.80GHz

N = 13:

criterion:
image

iai:

bench_thinvec_from_array_and_drop_large
  Instructions:                 331 (-37.66478%)
  L1 Accesses:                  426 (-38.61671%)
  L2 Accesses:                    3 (+50.00000%)
  RAM Accesses:                  14 (-22.22222%)
  Estimated Cycles:             931 (-30.20990%)

N = 1027:

criterion:
image

iai:

bench_thinvec_from_array_and_drop_huge
  Instructions:                 782 (-94.47896%)
  L1 Accesses:                 1063 (-94.26645%)
  L2 Accesses:                    7 (-80.00000%)
  RAM Accesses:                  90 (-4.255319%)
  Estimated Cycles:            4248 (-80.69530%)

Copy link
Copy Markdown
Collaborator

@emilio emilio left a comment

Choose a reason for hiding this comment

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

Two minor nits, but looks good.

///
/// - Capacity must be reserved in advance such that `capacity() > len()`.
pub unsafe fn push_reserved(&mut self, val: T) {
let old_len = self.len();
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Let's at least debug_assert!(old_len < self.capacity()); for good measure.

if hint > 0 {
self.reserve(hint);
}
for x in iter.by_ref().take(hint) {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Probably put it inside the hint > 0 for consistency?

@emilio emilio closed this in 90e23c3 Apr 8, 2026
@emilio
Copy link
Copy Markdown
Collaborator

emilio commented Apr 8, 2026

Merged it with some nits and going back to push_unchecked since I think it's more consistent with the _unchecked functions in std Vec.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants