← Back to Go Course | Chapter 14: Standard Library & HTTP | Lesson 9 of 10

Writing Benchmarks

A benchmark is a timed race for your code -- Go runs a piece of it over and over and reports exactly how fast (or slow) it is.

Anatomy of a Benchmark Function

A benchmark function repeats the code being measured b.N times, where Go's testing framework automatically picks N large enough to get a stable timing measurement -- shown here as a manually looped simulation.

Note: Real benchmarks live in _test.go files and run via 'go test -bench=.'; this simulates the same b.N loop pattern in main so it can run here.

Example: Anatomy of a Benchmark Function

markup
package main

import "fmt"

func fibonacci(n int) int {
	if n < 2 {
		return n
	}
	a, b := 0, 1
	for i := 2; i <= n; i++ {
		a, b = b, a+b
	}
	return b
}

func main() {
	const simulatedN = 1000
	for i := 0; i < simulatedN; i++ {
		fibonacci(20)
	}
	fmt.Println("ran fibonacci(20) simulatedN times:", simulatedN)
	fmt.Println("result:", fibonacci(20))
}

Excluding Setup from Timing

When a benchmark needs expensive setup before the loop (like building test data), calling b.ResetTimer() right after that setup excludes it from the measured time, so only the code under test is actually timed.

Example: Excluding Setup from Timing

markup
package main

import "fmt"

func sumSlice(nums []int) int {
	total := 0
	for _, n := range nums {
		total += n
	}
	return total
}

func main() {
	// setup (would be excluded from timing via b.ResetTimer() in a real benchmark)
	data := make([]int, 1000)
	for i := range data {
		data[i] = i
	}

	// timed portion
	result := sumSlice(data)
	fmt.Println("sum:", result)
}

Running Benchmarks

'go test -bench=.' runs every BenchmarkXxx function in a package, reporting how many iterations ran and the average time per operation, which is the standard way to compare performance across changes.

Example: Running Benchmarks

bash
go test -bench=.

⚠️ Run this command in your terminal.

Common Mistakes
  1. Naming a benchmark function without the exact Benchmark prefix, so 'go test -bench' won't discover it.
  2. Forgetting to loop the code under test b.N times inside the benchmark -- Go decides N automatically to get a stable measurement.
  3. Including one-time setup work inside the timed loop instead of resetting the timer with b.ResetTimer() after setup.
Chapter Summary
  • Benchmark functions are named BenchmarkXxx, take a *testing.B, and live in _test.go files.
  • The code being measured must run in a loop up to b.N, a count Go's testing framework adjusts automatically.
  • 'go test -bench=.' runs benchmarks and reports operations per second and time per operation.
  • b.ResetTimer() excludes setup work from the timed portion of a benchmark.

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.