Live data from Hacker News

Go Optimization Guide

goperf.dev

11–20 of 173 posts

Re: Go Optimization Guide

#11
Zero-copy is totally underrated. Like the site alludes to, Go's interfaces make it reasonably accessible to write zero-copy code but it still needs some careful crafting. The payoff is great though, I've often been surprised by how much time is spent allocating and shuffling memory around.

Re: Go Optimization Guide

#12
post #4

Additionally... - https://go101.org/optimizations/101.html - https://github.com/uber-go/guide I wish this content existed as a model context protocol (MCP) tool to connect to my IDE along w/ local LLM. After 6 months or switching between different language projects, it's challenging to remember all the important things.

Embedding those docs in your MCP server takes about 5 seconds with mcp-go's AddResource method

https://github.com/mark3labs/mcp-go/blob/main/examples/every...

Re: Go Optimization Guide

#13

You 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?

Re: Go Optimization Guide

#14

You 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?

I guess if you allocate more than you need upfront that it could increase memory usage.

Re: Go Optimization Guide

#15

Every 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…

Aren't allocations themselves pretty expensive regardless of GC?

Go 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.

Re: Go Optimization Guide

#16
GOMEMLIMIT has saved me a number of times. In containerized production, it's nice, because sometimes jobs are ephemeral and don't even do enough allocations to hit the memory limit, so you don't spend any time in GC. But it's saved me the most times in CI where golangci-lint or govulncheck can't complete without running out of memory on a kind-of-large CI machine. Set GOMEMLIMIT and it eventually completes. (I switched to nogo, though, so at least golangci-lint isn't a problem anymore.)

Re: Go Optimization Guide

#17
post #7

You're not really writing 'Go' anymore when you're optimising it, it's defeating the point of the language as a simple but powerful interface over networked services.

Why? You have control over the parts where control yields noticeable savings, and the rest just kind of works with reasonable defaults.

Taken to the extreme, Go is still nice even with constraints. For example, tinygo is pretty nice for microcontroller projects. You can say upfront that you don't want GC, and just allocate everything at the start of the program (kind of like how DJB writes C programs) and writing the rest of the program is still a pleasant experience.

Re: Go Optimization Guide

#18

Every 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…

You might wanna look at a system profiler too, pprof doesn't show everything.

Re: Go Optimization Guide

#19

Every 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…

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.

Re: Go Optimization Guide

#20

Every 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.
Post reply on HN