Comment by logicchains
3 years ago
> Having to decide ahead of time how much memory to allocate to the arena is... crap...
A nice solution in many cases is to just keep a bunch of std::vector<T> (or equivalent) around for the types you need, and .clear() them all at the start of each request/frame/message/whatever being processed. Calling push_back on a vector will only allocate when the vector's already reached its capacity, which will happen very rarely after the first few runs, so the hot loop will usually be allocation-free, but without needing to allocate a fixed amount of memory ahead of time.
Generally, std::vector not going to work for allocator backend.
The issue being, std::vector relocates all elements every time it increases the capacity. Therefore, adding an element to std::vector may invalidate addresses of all previously added vector elements.
You gonna have to adjust your higher-level data structures which use that allocator, replacing pointers with offsets relative to the start of that std::vector. This introduces another level of indirection, adds complexity, and in some edge cases may even ruin the performance.
std::vector is fine if you access elements by index, instead of pointer, which can be a perfectly fine approach. Of course this kills the general purpose allocator aspect, since you're not getting back pointers, only offsets.
However, if you combine that with generation numbers, you can make yourself a very handy container with stable and safe references. slotmap [1] comes to mind.
[1]: https://docs.rs/slotmap/latest/slotmap/
Yes, that's true if you need higher-level datastructures, but if your functions are just taking vectors/spans of stuff as input then it works out fine.
std::deque, although it would be nice to use an implementation where you can control the block size.
Here’s a simple non-standard allocator for C++ I used a few times in the past: https://github.com/Const-me/CollectionMicrobench/blob/master...
The block size is controlled with a template argument, the number must be a compile-time constant.