A fast bump allocation arena for Rust.
Bump allocation is a fast, but limited approach to allocation. We have a chunk of memory, and we maintain a pointer within that memory. Whenever we allocate an object, we do a quick test that we have enough capacity left in our chunk to allocate the object and then update the pointer by the object's size. That's it!
The disadvantage of bump allocation is that there is no general way to deallocate individual objects or reclaim the memory region for a no-longer-in-use object.
These trade offs make bump allocation well-suited for phase-oriented allocations. That is, a group of objects that will all be allocated during the same program phase, used, and then can all be deallocated together as a group.
To deallocate all the objects in the arena at once, we can simply reset the bump
pointer back to the start of the arena's memory chunk. This makes mass
deallocation extremely fast, but allocated objects' Drop
implementations are
not invoked.
This implementation will allocate a new memory chunk from the global allocator and then start bump allocating into this new memory chunk.
use bumpalo::Bump;
use std::u64;
struct Doggo {
cuteness: u64,
age: u8,
scritches_required: bool,
}
// Create a new arena to bump allocate into.
let bump = Bump::new();
// Allocate values into the arena.
let scooter = bump.alloc(Doggo {
cuteness: u64::max_value(),
age: 8,
scritches_required: true,
});
assert!(scooter.scritches_required);
When the "collections"
cargo feature is enabled, a fork of some of the std
library's collections are available in the collections
module. These
collection types are modified to allocate their space inside bumpalo::Bump
arenas.
use bumpalo::{Bump, collections::Vec};
// Create a new bump arena.
let bump = Bump::new();
// Create a vector of integers whose storage is backed by the bump arena. The
// vector cannot outlive its backing arena, and this property is enforced with
// Rust's lifetime rules.
let mut v = Vec::new_in(&bump);
// Push a bunch of integers onto `v`!
for i in 0..100 {
v.push(i);
}
Eventually all std
collection types will be parameterized by an
allocator and we can remove
this collections
module and use the std
versions.
Bumpalo is a no_std
crate. It depends only on the alloc
and core
crates.