Performance: resources¶
Level: 301 · where the lessons of this chapter came from, and what to read next
One line: The primary sources are the testing package's documentation, the compiler's own source for its budgets and messages, and the Go blog's posts on b.Loop, profiling and PGO; the books cover benchmarking and profiling in their testing chapters; and a good deal of older advice about benchmark loops and inlining no longer describes Go 1.25.
Primary sources¶
testing, Benchmarks ↗,B.Loop↗,B.ReportAllocs↗,Benchmark↗,BenchmarkResult↗ andAllocsPerRun↗ — what a benchmark is, whatLoopguarantees, what the result holds.go help testflag↗ —-bench,-benchmem,-benchtime,-count,-cpuprofile,-memprofile,-trace.- Go 1.24 release notes,
testing↗ and Junyang Shao, More predictable benchmarking with testing.B.Loop ↗, the Go blog, April 2025 — whyb.Loopreplaced theb.Nloop. cmd/compile↗ — the-mand-dflags and the//go:noinlinedirective;src/cmd/compile/internal/inline/inl.go↗ — the budget of 80, the extra call cost of 57, the hot budget of 2000, and everycannot inlinemessage.- Go 1.16 release notes ↗ and Go 1.18 release notes ↗ — inlining of functions with
forloops, thenrangeand labeled loops; Go 1.21 release notes ↗ — profile-guided optimization ready for general use. - Profile-guided optimization ↗ and Profile-guided optimization in Go 1.21 ↗ — how a profile raises the inlining budget on the hot path.
src/cmd/compile/internal/ssa/checkbce.go↗ andprove.go↗ — the debug pass that lists bounds checks and the pass that removes them; issue 14808 ↗ — the_ = b[3]hint.- The Go wiki, Compiler And Runtime Optimizations ↗ — escape analysis, inlining and the other things
-gcflags=-mreports. runtime/pprof↗,runtime/trace↗,go tool trace↗ and thepprofdocumentation ↗ — collecting and reading profiles and traces; the profile format ↗.- Russ Cox and Shenghou Ma, Profiling Go Programs ↗, the Go blog, 2011 (updated 2013) — still the clearest walk from a slow program to a fast one; Diagnostics ↗ — the map of profiling, tracing, debugging and runtime statistics; More powerful Go execution traces ↗.
benchstat↗ — comparing sets of benchmark runs; outside the standard library.- The runtime sources behind the allocation counts:
iface.go↗,string.go↗,slice.go↗,sizeclasses.go↗ andstrconv/itoa.go↗. - The GC guide ↗ — what allocation costs after the allocation; the chapter Memory and the runtime is this library's take.
Books¶
- Alan Donovan and Brian Kernighan, The Go Programming Language (Addison-Wesley, 2015), chapter 11, "Testing" — 11.4, "Benchmark Functions" (the
b.Nloop of its day,-benchmem, and why absolute times mislead) and 11.5, "Profiling" (-cpuprofile,-memprofile,-blockprofileandgo tool pprof). - Jon Bodner, Learning Go, 2nd ed. (O'Reilly, 2024), chapter 15, "Writing Tests" — "Using Benchmarks", with the box "Profiling Your Go Code"; chapter 6, "Pointers" — "Reducing the Garbage Collector's Workload" and "Tuning the Garbage Collector".
- Go in Practice, 2nd ed. (Manning, 2025), chapter 6, "Formatting, testing, debugging, and benchmarking" — 6.4, "Benchmarking and performance tuning".
- Adam Freeman, Pro Go (Apress, 2022), chapter 31, "Unit Testing, Benchmarking, and Logging" — "Benchmarking Code" and "Removing Setup from the Benchmark" (
ResetTimer,StopTimer,StartTimer, whichb.Loopnow handles for the common case). - Miki Tebeka, Effective Go Recipes (Pragmatic, 2024), Recipe 33, "Calculating Cumulative Sum" — a benchmark, its allocations, and a CPU profile read with
top; Recipe 56, "Using sync/atomic for a Faster Now" — a benchmark deciding between two designs; Recipe 75, "Using Build Tags for Conditional Builds" —net/http/pprofbehind a build tag.
Not on the shelf¶
- Bartłomiej Płotka, Efficient Go (O'Reilly, 2022): https://www.oreilly.com/library/view/efficient-go/9781098105709/ — a whole book on the measure-first discipline this chapter practises in five pages.
- Teiva Harsanyi, 100 Go Mistakes and How to Avoid Them (Manning, 2022): https://www.manning.com/books/100-go-mistakes-and-how-to-avoid-them — its optimization chapter collects the benchmarking mistakes.
Talks and videos¶
- Jacob Walker, Understanding Allocations: the Stack and the Heap ↗, GopherCon SG 2019 — the talk behind
AllocsPerRuncounts allocations and chapter 14's escape analysis lesson. - Dave Cheney, High Performance Go Workshop ↗, GopherCon 2019 — a written workshop covering benchmarking, profiling, tracing, the compiler's
-moutput and bounds-check elimination, from the same starting point as this chapter.
Read with care¶
- Benchmark tutorials written before Go 1.24, with
for i := 0; i < b.N; i++. The loop still works, but it runs the benchmark function several times, times whatever setup sits above it on every round, and does nothing to stop the compiler discarding an unused result —allocs/opis a key,ns/opis not. - "Functions with loops cannot be inlined." True before Go 1.16 for
forloops and before 1.18 forrangeloops; the lesson The compiler says what it inlines showssumToinlined with its loop. - Tables of
ns/opquoted as facts. Every such number is one machine on one day; without the machine, the Go version and the number of runs, it cannot be compared with anything. - "
fmt.Sprintfallocates N times." The count depends on whether the arguments are constants, small integers or run-time values —AllocsPerRuncounts allocations shows 1 and 2 for the same format string. - Advice to remove bounds checks with
unsafe. The prove pass removes the common shapes by itself, and a benchmark is the only way to know whether the remaining checks cost anything — Bounds checks, and how to drop them.
Checked 2026-09-23.