Skip to content

Commit 9abc231

Browse files
committed
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`
2 parents 0765eb9 + 95f32f1 commit 9abc231

File tree

1 file changed

+14
-10
lines changed

1 file changed

+14
-10
lines changed

src/libarena/lib.rs

+14-10
Original file line numberDiff line numberDiff line change
@@ -224,14 +224,14 @@ impl<T> TypedArena<T> {
224224
unsafe {
225225
// Clear the last chunk, which is partially filled.
226226
let mut chunks_borrow = self.chunks.borrow_mut();
227-
if let Some(mut last_chunk) = chunks_borrow.pop() {
227+
if let Some(mut last_chunk) = chunks_borrow.last_mut() {
228228
self.clear_last_chunk(&mut last_chunk);
229+
let len = chunks_borrow.len();
229230
// If `T` is ZST, code below has no effect.
230-
for mut chunk in chunks_borrow.drain(..) {
231+
for mut chunk in chunks_borrow.drain(..len-1) {
231232
let cap = chunk.storage.cap();
232233
chunk.destroy(cap);
233234
}
234-
chunks_borrow.push(last_chunk);
235235
}
236236
}
237237
}
@@ -311,13 +311,8 @@ impl Default for DroplessArena {
311311
impl DroplessArena {
312312
pub fn in_arena<T: ?Sized>(&self, ptr: *const T) -> bool {
313313
let ptr = ptr as *const u8 as *mut u8;
314-
for chunk in &*self.chunks.borrow() {
315-
if chunk.start() <= ptr && ptr < chunk.end() {
316-
return true;
317-
}
318-
}
319314

320-
false
315+
self.chunks.borrow().iter().any(|chunk| chunk.start() <= ptr && ptr < chunk.end())
321316
}
322317

323318
#[inline]
@@ -410,7 +405,7 @@ impl DroplessArena {
410405
{
411406
assert!(!mem::needs_drop::<T>());
412407
assert!(mem::size_of::<T>() != 0);
413-
assert!(slice.len() != 0);
408+
assert!(!slice.is_empty());
414409

415410
let mem = self.alloc_raw(
416411
slice.len() * mem::size_of::<T>(),
@@ -606,6 +601,15 @@ mod tests {
606601
}
607602
}
608603

604+
#[bench]
605+
pub fn bench_typed_arena_clear(b: &mut Bencher) {
606+
let mut arena = TypedArena::default();
607+
b.iter(|| {
608+
arena.alloc(Point { x: 1, y: 2, z: 3 });
609+
arena.clear();
610+
})
611+
}
612+
609613
// Drop tests
610614

611615
struct DropCounter<'a> {

0 commit comments

Comments
 (0)