Earlier quoted context omitted.
Aren't allocations themselves pretty expensive regardless of GC?
No. If you have a moving multi generational GC, allocation is literally just an increment for short lived objects.
Go Optimization Guide
31–40 of 173 posts
Re: Go Optimization Guide
#32Every perf guide recommends to minimize allocations to reduce GC times, but if you look at pprof of a Go app, GC mark phase is what takes time, not GC sweep. GC mark always starts with known live roots (goroutine stacks, globals, etc) and traverse references from there colouring every pointer. To minimize GC time it is best to avoid _long living_ allocations. Short lived allocations, those which GC mark phase will ne…
Pretty similar story in .NET. Make sure your inner loops are allocation-free, then ensure allocations are short-lived, then clean up the long tail of large allocations.
Doing huge allocations which go to LOH is quite punishing, but even substantial inter-generational traffic won't kill it.
Re: Go Optimization Guide
#33Earlier quoted context omitted.
Why would Pool increase memory usage?
I guess if you allocate more than you need upfront that it could increase memory usage.
Re: Go Optimization Guide
#34Re: Go Optimization Guide
#35Every perf guide recommends to minimize allocations to reduce GC times, but if you look at pprof of a Go app, GC mark phase is what takes time, not GC sweep. GC mark always starts with known live roots (goroutine stacks, globals, etc) and traverse references from there colouring every pointer. To minimize GC time it is best to avoid _long living_ allocations. Short lived allocations, those which GC mark phase will ne…
Its worth calling out that abstractions can kill you in unexpected ways with go. Anytime you use an interface it forces a heap allocation, even if the object is only used read only and within the same scope. That includes calls to things like fmt.Printf() so doing a for loop that prints the value of i forces the integer backing i to be heap allocated, along with every other value that you printed. So if you helpfully…
Re: Go Optimization Guide
#36Earlier quoted context omitted.
Its worth calling out that abstractions can kill you in unexpected ways with go. Anytime you use an interface it forces a heap allocation, even if the object is only used read only and within the same scope. That includes calls to things like fmt.Printf() so doing a for loop that prints the value of i forces the integer backing i to be heap allocated, along with every other value that you printed. So if you helpfully…
I thought surely an integer could be inlined into the interface, I thought Go used to do that. But I tried it on the playground, and it heap allocates it: https://go.dev/play/p/zHfnQfJ9OGc
Re: Go Optimization Guide
#37Every perf guide recommends to minimize allocations to reduce GC times, but if you look at pprof of a Go app, GC mark phase is what takes time, not GC sweep. GC mark always starts with known live roots (goroutine stacks, globals, etc) and traverse references from there colouring every pointer. To minimize GC time it is best to avoid _long living_ allocations. Short lived allocations, those which GC mark phase will ne…
Re: Go Optimization Guide
#38Anyone know of a resource like this but for Python 3?
Re: Go Optimization Guide
#39Re: Go Optimization Guide
#40You can often fool yourself by using sync.Pool. pprof looks great because no allocs in benchmarks but memory usage goes through the roof. It's important to measure real world benefits, if any, and not just synthetic benchmarks.
Why would Pool increase memory usage?
So, if you have predictable object sizes, the pool will stay flat. If the workloads are random, you have a new problem because, like in this scenario, your pool grows 5x more.
You can solve this problem. E.g. you can only give back items into the pool that are small enough. Alternatively, you could have a small pool and a big pool, but now you're playing cat and mouse.
In such a scenario, it could also work to simply allocate and use GC to clean up. Then you don't have to worry about memory and the lifetime of objects, which makes your code much simpler to read and reason about.