8 ms·
It is simply not true unless you have a pathological idea of "hand-allocation" (which to be fair, some programmers do program like). Let me put it this way ...
by jblow 9y ago
It is simply not true unless you have a pathological idea of "hand-allocation" (which to be fair, some programmers do program like).
Let me put it this way ... all "garbage collection is fast" claims are saying the following thing:
"It is faster for the programmer to destroy information about his program's memory use (by not putting that information into the program), and to have the runtime system dynamically rediscover that information via a constantly-running global search and then use what it gleans to somehow be fast, than it is for the programmer to just exploit the information that he already knows."
It sure sounds like nonsense to me.
- vvanders 9y agoYup, 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]
- 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.
- walkingolof 9y agoHeap allocation and smartpointers (as an alternative to GC) is by no means free, in that context GC performance favorable in many scenarios, for example when doing large number of small allocations. But in the end, if your application have serious performance requirements, you should avoid allocating memory in the hot path altogether.
- _ph_ 9y agoSo much this. GCs don't mean you shouldn't care about reasonable memory allocations. In hot paths, not allocating will always be faster than allocating. Having a GC does not prevent you from using object pools and buffers, where it is a clear performance win. But having a GC means, you are not required to do so, where there is no bottle neck. The difference between a "fast" and a "slow" GCed language often is, how well the programmer keeps some control about memory allocations. Fun fact: the Go GC is written in pure Go code, which does not perform any heap allocations. So there is enough control to write code in Go which does not require any heap allocations. There is even a compiler switch for the development of the GC code which makes heap allocations a compile error.
- _ph_ 9y agoYou are talking about an abstract case. Yes, if an objects lifetime is perfectly easy to determine, manual memory management is faster. But in many typical programs with real dynamic memory requirements, this is not the case. One has to keep track about the life time of objects in the program logic. Either by storing additional information as for reference counting, or careful designing your program logic so the status of an object is always clearly known. The latter might not bear a cost in CPU cycles, but certainly in programmer cycles, if the program logic allows for it at all. It also puts the burden of correctness on the programmer vs the garbage collector. And for most contemporary programs, correctness is the larger challenge then execution speed, especially with GCs which can run in parallel with your program logic, so can utilize unused CPUs "for free".
- mcguire 9y ago"This paper presents a tracing and simulation-based experimental methodology that executes unaltered Java programs as if they used explicit memory management. We use this framework to compare the time-space performance of a range of garbage collectors to ex- plicit memory management with the Lea memory allocator. Com- paring runtime, space consumption, and virtual memory footprints over a range of benchmarks, we show that the runtime performance of the best-performing garbage collector is competitive with ex- plicit memory management when given enough memory. In par- ticular, when garbage collection has five times as much memory as required, its runtime performance matches or slightly exceeds that of explicit memory management. However, garbage collec- tion’s performance degrades substantially when it must use smaller heaps. With three times as much memory, it runs 17% slower on average, and with twice as much memory, it runs 70% slower. Gar- bage collection also is more susceptible to paging when physical memory is scarce. In such conditions, all of the garbage collectors we examine here suffer order-of-magnitude performance penalties relative to explicit memory management." http://people.cs.umass.edu/~emery/pubs/gcvsmalloc.pdf http://people.cs.umass.edu/~emery/pubs/gcvsmalloc.pdf [2005] Consider what happens when you allocate or free memory manually: the manager had to do some amount of work to track the status of the memory. Now consider a 2-space, moving collector. Allocation is a pointer bump and range check. Collection means tracing and copying the live objects. That's it. It's not as simple as it seems.