4 ms·
Yup, an arena allocator that you drop at the end of an operation will always be faster than a GC.
by vvanders 9y ago
Yup, an arena allocator that you drop at the end of an operation will always be faster than a GC.
- gsb 9y agoAbsolutely, but I think the "in most cases" of the original quote was meant to imply simple malloc/free style memory management rather than the use of tailored arena/region allocators.
- _yosefk 9y agoWell, yeah, but if you need some of the allocated data at the end of the operation, you'll end up copying it, which will have a runtime cost, might introduce bugs (because of pointer invalidation and the ease of forgetting to update some pointers) and then none of the two will get counted as "cost of manual memory management." C++ with its value semantics encourages unnecessary copying tremendously and it's never counted as "cost of memory allocation" or "producing garbage", on the contrary, Stroustrup says things like "C++ is my favorite GC language because it generates so little garbage to begin with." This is not to say that it's fair to call OCaml "efficient" in the memory department based on a GC benchmark; TFA is full of examples where OCaml allocates things on the heap that TFA recommends to allocate elsewhere and shows you how to maul your code to get there. My only point is that how well a programming system uses memory is a very hard question because (A) there are many different use cases and (B) you can't isolate "memory performance" into a few easily measurable things like time spent allocating, time spent in GC and peak memory use - there are other things like what your program has to do outside of the allocator to cope with its semantics and how the performance of code using the memory objects is affected by the layout encouraged by the allocator and these things cannot be measured in isolation from the rest of the program.
- rbehrends 9y agoFor a modern generational GC, the minor heap works just like an arena allocator (at least for the data that can be thrown away), so this shouldn't result in any performance difference (assuming the minor heap is large enough).
- _yosefk 9y agoIsn't it harder to deallocate the data if you actually check that it's unused, as a GC must, instead of just assuming it?
- rbehrends 9y agoUnused data is by definition unreachable from any GC roots and should not incur additional tracing work.
- ori_b 9y agoThat means that the heap grows with the highest address allocated within it, unless you incur additional overhead for copying the data around.
- rbehrends 9y agoThis is exactly what a generational GC does. Once the minor heap fills up, it evicts data that is still in use and moves it to the major heap. Note that this overhead is only incurred for data still in use. We are not comparing memory management strategies in general, but the special case of temporarily allocating data that can be thrown away at the end.
- ori_b 9y agoIt is also not what an arena allocator does.
- deleted 9y ago[deleted]
- barrkel 9y agoA GC doesn't check if memory is unused; it looks for memory that's used and frees whatever is leftover. Having a small fraction of used memory to total memory is what makes GC cheap (in compute time). It also means that allocating short-lived memory with abandon is cheap, if that's most of your allocation.
- rwmj 9y agoThat could blow away your cache if the arena is large. Better to measure it.
- pjmlp 9y agoNot if you have cascaded data structures, have some kind of destructor like operations to call, synchronize threads, or if the memory allocator does a call into the OS to release the memory back to the OS.
- mcguire 9y agoArenas are probably the fastest memory management technique this side of fixed allocation and stacks. If the lifetime of the objects is contained within the lifetime of the arena. If not, you have to copy live objects out before you destroy the arena, at which point you are implementing a n-space moving collector.