Should I allocate a Vec with bumpalo?

I need arrays allocated dinamically and possibly recycled when needed. I found GitHub - fitzgen/bumpalo: A fast bump allocation arena for Rust but it looks like it does not support allocating direct slices. Should I allocate a vector like this:


use bumpalo::{Bump, collections::Vec};
let bump = Bump::new();
let mut v = Vec::new_in(&bump);

and get its slice every time I need it?

Problem is that I can't force the vector to have the exact size I want. My arrays always have a fixed size, they don't grow. I think Vec is for things that grow.

Slices (slice references) don't own their elments, vectors do. Anything that allocates has to have ownership semantics in order to clean up itself properly and not leak memory, hence you can't "allocate a slice", you will in fact have to allocate a vector. There's nothing wrong with that – you can use it without growing it. If you are concerned about the extra "capacity" field of the vector taking up a word, you might as well use bumpalo::boxed::Box<[T]> instead.

I was reading earlier today about mimalloc. From what I learned, I think that if you are on a platform where mimalloc is available, it's probably not worth worrying about arenas and allocation speed-up techniques, the overhead of allocating is pretty low. I mean, I guess it's maybe 20 CPU instructions, or something of that order (totally off the top of my head...). It's still worth trying to avoid heap allocations if you can, but I think (and maybe I am wrong) there is a wrong impression that heap allocation is "super-expensive".

Maybe you want an array [T; N], where the size is part of the type.

wouldn't I have to create the array [T] in the stack first? This makes it impossible because the size is known at runtime. Is there a way to allocate a Box<[T]> for a really large size, so nothing in the stack? Also, no extra copying from stack to allocated

vec![0; N].into_boxed_slice()

3 Likes

but this wouldn't be useful on bumpalo, as it would allocate a place for the box that vec![0; N].into_boxed_slice() returns. Nothing more than that, right?

I think the allocation should happen inside bumpalo somehow

Why do you want to use bumpalo at all?

The bumpalo Box and Vec work basically the same as the ones in std, right down to growth and reallocation for Vec, except that bumpalo allocations can't be reused unless you leak everything currently being stored in the allocator. Given that you are concerned about recycling unused memory, this seems like something you don't want. The standard allocator will probably suit you better, since it can reuse individual allocations without dumping the whole heap on the floor.

3 Likes

The mimalloc paper has this to say:

"Many allocators use a reap design where a bump pointer is used initially when the page is empty (Berger et al., 2002; Feng and Berger, 2005; Liétar et al., 2019). We tested a variant of mimalloc with bump pointer allocation but across our benchmarks it was consistently about 2% worse."

They go on to discuss why this might be the case. Anyway, I doubt there are any easy gains to be had ( although not all allocators are equal - under certain conditions some allocators behave badly, see the paper for details. ).

sorry I'm lost, I thought bumpalo was like a memory pool on C++. Let's say that I allocated an array with size 1000 and I'm not using anymore, then when I try to allocate an array with size 900 it can use that allocated slice pointer and send to me (possibly zero it first). This is what I want.

What would be the correct way to allocate a very big array dinamically with std only? No allocation on stack, but directly on heap.

I want recycling after all.

bumpalo is a very specific append-only memory pool. It only bumps a pointer to pre-allocated memory. It doesn't support freeing or recycling of memory, other than via destruction of the entire pool.

The use-case for bumpalo is when you need to make millions of individual allocations, and then drop them all at once (IIRC it's been developed for virtual DOM, which copies entire tree structures on every render frame).

If you can work with [T; N] arrays, check other crates like typed arena.

3 Likes

doesn't allocating arrays require unsafe? typed_arena::Arena - Rust

Otherwise I need to pass an allocated array on the stack, which is what I'm trying to avoid

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.