A benchmark repeatedly runs code to measure performance. In Go, benchmarks complement tests and profiling: they establish current execution costs, reveal regressions after changes, and help identify bottlenecks before they become expensive. Optimize for a business need, not by default; stop when a speedup makes code harder to maintain. section 3.2 section 3.0
Write a benchmark in a test file with a Benchmark prefix and a *testing.B parameter. Put the code being measured inside a b.Loop loop; the testing package runs it enough times to measure it. Run benchmarks with go test and -bench=.; add -benchmem to report ns/op, B/op, and allocs/op—time, heap bytes, and allocations per operation. section 3.2.1 section 3.3.3
Measure a URL formatter
BenchmarkURLString creates a representative URL once, then calls String inside b.Loop while discarding the unneeded result. Setup stays outside the measured loop. A run can show roughly 96 ns/op, 64 B/op, and four allocations per String call; changing the benchmark duration with -benchtime can collect a longer sample. section 3.2.1
Use benchmarks to investigate realistic changes rather than chase isolated numbers:
- Use sub-benchmarks with b.Run to measure input sizes separately. Increasing URL lengths shows how time and bytes per operation scale while retaining a comparable allocation count. section 3.2.2
- Compare saved old and new results relatively with benchstat. Repeated measurements expose changes in time, memory, and allocations; alternating versions reduces bias from temperature, CPU frequency, background work, and garbage collection. section 3.2.5
- Treat implausibly tiny timings as a warning. Pure calls whose results are unused can be inlined and removed, leaving a benchmark that measures only its loop. Prefer b.Loop and do not mix it with b.N. section 3.3.1 section 3.3.3
Figure 3.2 Benchmarking the code in a loop to measure performance
The loop model makes the boundary clear: construct stable input outside the loop, repeatedly execute only the operation being measured inside it, and let the benchmark runner collect measurements. section 3.2.1






















