diff options
| author | bors <bors@rust-lang.org> | 2018-12-02 11:14:14 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2018-12-02 11:14:14 +0000 |
| commit | 9abc2312124de7c4275d76e9cbc81d50086c4768 (patch) | |
| tree | 78b81359a2d7a8805cb5b846e1a6918b7bf28671 | |
| parent | 0765eb95b5e9e15fc29aa7725a01621dfeca2649 (diff) | |
| parent | 95f32f1ebddae26ac6610040ea93ea3de440089a (diff) | |
| download | rust-9abc2312124de7c4275d76e9cbc81d50086c4768.tar.gz rust-9abc2312124de7c4275d76e9cbc81d50086c4768.zip | |
Auto merge of #56378 - ljedrz:arena_tweaks, r=nagisa
arena: speed up TypedArena::clear and improve common patterns - speed up `TypedArena::clear`: improves its performance by up to **33%** (in case of a single entry) - simplify `DroplessArena::in_arena`
| -rw-r--r-- | src/libarena/lib.rs | 24 |
1 files changed, 14 insertions, 10 deletions
diff --git a/src/libarena/lib.rs b/src/libarena/lib.rs index 955cab1d93f..aef3edd9eb6 100644 --- a/src/libarena/lib.rs +++ b/src/libarena/lib.rs @@ -224,14 +224,14 @@ impl<T> TypedArena<T> { unsafe { // Clear the last chunk, which is partially filled. let mut chunks_borrow = self.chunks.borrow_mut(); - if let Some(mut last_chunk) = chunks_borrow.pop() { + if let Some(mut last_chunk) = chunks_borrow.last_mut() { self.clear_last_chunk(&mut last_chunk); + let len = chunks_borrow.len(); // If `T` is ZST, code below has no effect. - for mut chunk in chunks_borrow.drain(..) { + for mut chunk in chunks_borrow.drain(..len-1) { let cap = chunk.storage.cap(); chunk.destroy(cap); } - chunks_borrow.push(last_chunk); } } } @@ -311,13 +311,8 @@ impl Default for DroplessArena { impl DroplessArena { pub fn in_arena<T: ?Sized>(&self, ptr: *const T) -> bool { let ptr = ptr as *const u8 as *mut u8; - for chunk in &*self.chunks.borrow() { - if chunk.start() <= ptr && ptr < chunk.end() { - return true; - } - } - false + self.chunks.borrow().iter().any(|chunk| chunk.start() <= ptr && ptr < chunk.end()) } #[inline] @@ -410,7 +405,7 @@ impl DroplessArena { { assert!(!mem::needs_drop::<T>()); assert!(mem::size_of::<T>() != 0); - assert!(slice.len() != 0); + assert!(!slice.is_empty()); let mem = self.alloc_raw( slice.len() * mem::size_of::<T>(), @@ -606,6 +601,15 @@ mod tests { } } + #[bench] + pub fn bench_typed_arena_clear(b: &mut Bencher) { + let mut arena = TypedArena::default(); + b.iter(|| { + arena.alloc(Point { x: 1, y: 2, z: 3 }); + arena.clear(); + }) + } + // Drop tests struct DropCounter<'a> { |
