4 ms·
Aren't allocations themselves pretty expensive regardless of GC?
by Capricorn2481 2y ago
Aren't allocations themselves pretty expensive regardless of GC?
- nu11ptr 2y agoGo allocations aren't that bad. A few years ago I benchmarked them at about 4x as expensive as a bump allocation. That is slow enough to make an arena beneficial in high allocation situations, but fast enough to not make it worth it most of the time.
- aktau 2y agoComparing with a fairly optimized malloc at $COMPANY, the Go allocator is (both in terms of relative cycles and fraction of cycles of all Go programs) significantly more expensive than the C/C++ counterpart (3-4x IIRC). For one, it has to do more work, like setting up GC metadata, and zeroing. There have recently been some optimizations to `runtime.mallocgc`, which may have decrease that 3-4x estimate a bit.
- nu11ptr 2y agoHow can that be true? If it is 3-4x more expensive than malloc, then per my measurements your malloc is a bump allocator, and that simply isn't true for any real world malloc implementation (typically a modified free list allocator afaik). `mallocgc` may not be fast, but I simply did not find it as slow as you are saying. My guess is it is about as fast as most decent malloc functions, but I have not measured, and it would be interesting to see a comparison (tough to do as you'd need to call malloc via CGo or write one in C and one in Go and trust the looping is roughly the same cost).
- aktau 2y agoI should correct and clarify: I meant 3-4x more expensive in relative terms. Meaning: - For C++ programs, the allocator (allocating+freeing) consumes roughly 5% of cycles. - For Go programs, the allocator (runtime.mallocgc) used to consume ~20% of cycles (this is the data I referenced). I checked and recently it's become closer to 15%, thanks to optimizations. I have not tested the performance differential on a per-byte level (though that will also differ with object structure in Go).
- epcoa 2y agoNo. If you have a moving multi generational GC, allocation is literally just an increment for short lived objects.
- deleted 2y ago[deleted]
- burch45 2y agoThis is about go not Java. Go makes different tradeoffs and does not have moving multigenerational GC.
- deleted 2y ago[deleted]
- pebal 2y agoIf you have a moving, generational GC, then all the benefits of fast allocation are lost due to data moving and costly memory barriers.
- deleted 2y ago[deleted]
- gf000 2y agoNot at all. Most objects die young and thus are never moved. Also, the time before it is moved is very long compared to CPU operations so it is only statistically relevant (very good throughput, rare, longer tail on latency graphs). Also, write-only barriers don't have that big of an overhead.
- pebal 2y agoIt doesn't matter if objects die young — the other objects on the heap are still moved around periodically, which reduces performance. When you're using a moving GC, you also have additional read barriers that non-moving GCs don't require.