Commit 8597392
Optimize Vec push by preventing address escapes
This change makes RawVecInner non-generic over the allocator, allowing it
to be Copy. The allocator is moved to RawVec itself. Key optimizations:
- RawVecInner is now Copy (no allocator field)
- grow_one uses ptr::read/ptr::write to copy allocator to a temporary,
preventing &self from escaping through &dyn Allocator parameter
- Drop::drop similarly copies to temporaries before deallocating
- deallocate takes self by value instead of &mut self
- All these functions are #[inline(always)]
This allows LLVM to keep Vec fields (cap, ptr, len) in registers during
push loops instead of storing/loading from memory every iteration.
Benchmark results (push with pre-allocated capacity):
- 100 elements: 1.74x faster
- 1000 elements: 1.87x faster
- 10000 elements: 2.41x faster
Secondary benefit: grow_one_impl and other growth functions use &dyn Allocator,
so they are compiled once in libstd rather than monomorphized per allocator type.
Preserves const compatibility with the const_heap feature by using generics
for the const allocation path while using &dyn Allocator for runtime paths.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>1 parent 1b9ae9e commit 8597392
4 files changed
Lines changed: 185 additions & 150 deletions
0 commit comments