4 ms·
It makes a difference. Back in my C# days, a team rewrote an internal service in a C-like fashion: structs, no properties, almost no runtime heap allocations. T
by christophilus 5y ago
It makes a difference. Back in my C# days, a team rewrote an internal service in a C-like fashion: structs, no properties, almost no runtime heap allocations. The application absolutely screamed. If I recall, it was 2 or more orders of magnitude faster than the app it replaced. Because it was highly used, this made a big difference, and enabled new use cases that weren’t possible previously.
You see the same thing in Go. Libraries that are zero-allocating are significantly faster than the competition.
- kaba0 5y agoDepends. Of course it is generally preferable to do no heap allocation but the latter is very cheap as well with good GCs, and the reclamation process is amortized/can be done in parallel for the most time. Eg. Java’s allocations are like 3 CPU instructions if I’m not mistaken?
- elteto 5y agoIt’s not the allocation that necessarily kills you, it’s the garbage collection.
- kaba0 5y agoBut that depends on the number of objects. So unless you are creating objects like there is no tomorrow in a hot loop, the GC should be able to keep up with your workload quite well.
- anamax 5y agoGC will cost 50-100 instructions per object reclaimed AND 5-10 per object not reclaimed. Even if we ignore the latter, gc will can add 2x for objects that you don't do much with. And then there's the cache effects. Close to top-of-stack is pretty much guaranteed to be in L1 and might even be in registers. Heap allocated stuff is wherever. Yes, usually L2/L3 but that's at >2x the latency for the first access.
- kaba0 5y agoIs your instruction numbers from a generational GC? Not doubting it, but perhaps that can further amortize the cost (new objects that are likely to die are looked at more often). Cache misses are indeed true, but I think we should not pose the problem as if the two alternatives are GCs with pointer chasing and some ultra-efficient SoA or array-based language. Generally, most programs will require allocations and those will cause indirections, or they will simply not loop over some region of memory at all. Then GC really is cheap and may be the better tradeoff (faster allocation, parallel reclaim). But yeah, runtimes absolutely need a way for value classes.
- anamax 5y agoGenerational affects the number of free objects that can be found, not the cost of freeing or looking at an object, or even the number of objects looked at. I thought that the comparison was between "heap-allocate every object" vs "zero allocation." (C/C++ and similar languages which make it easy to stack-allocate objects, which is not far from zero-allocation.) If the application is such that zero-allocation isn't easy, then that comparison doesn't make sense. However, we're discussing situations when zero (or stack) allocation is possible.
- loldot_ 5y agoAllocations are pretty cheap, but GC can be quite expensive under high load/big heap. It is probably not the first optimization you would need to make, but allocaitons have been a huge focus by the .net core team, and is part of the reason why it is so much faster than the .net full framework. See for example the post on improvements in dotnet 5: https://devblogs.microsoft.com/dotnet/performance-improvements-in-net-5/#gc https://devblogs.microsoft.com/dotnet/performance-improvemen... https://docs.microsoft.com/en-us/aspnet/core/performance/performance-best-practices?view=aspnetcore-6.0#minimize-large-object-allocations https://docs.microsoft.com/en-us/aspnet/core/performance/per... https://docs.microsoft.com/en-us/dotnet/standard/garbage-collection/performance https://docs.microsoft.com/en-us/dotnet/standard/garbage-col...