Go > Testing and Benchmarking > Benchmarking > Running benchmarks
Basic Benchmarking in Go
This snippet demonstrates how to write and run benchmarks in Go to measure the performance of a function. Benchmarking is crucial for identifying performance bottlenecks and optimizing code.
Writing a Benchmark Function
Benchmark functions in Go reside in the same packages as your tests, identified by names starting with `Benchmark`. The `testing.B` type provides methods for timing and controlling the benchmark execution. The `b.N` variable represents the number of iterations the benchmark will run. The `fibonacci` function is a simple recursive function that will be benchmarked.
package main
import "testing"
func fibonacci(n int) int {
if n <= 1 {
return n
}
return fibonacci(n-1) + fibonacci(n-2)
}
func BenchmarkFibonacci10(b *testing.B) {
for i := 0; i < b.N; i++ {
fibonacci(10)
}
}
Running the Benchmark
To run the benchmark, use the `go test` command with the `-bench` flag. The `.` pattern means run all benchmarks in the current directory. The `-benchmem` flag includes memory allocation statistics in the benchmark results.
// Save the above code in a file named fib_test.go
// Navigate to the directory containing fib_test.go in your terminal.
go test -bench=. -benchmem
Interpreting the Benchmark Results
The output shows the benchmark name (`BenchmarkFibonacci10`), the number of iterations (`1708552`), the average time per operation (`686.3 ns/op`), bytes allocated per operation (`0 B/op`), and the number of memory allocations per operation (`0 allocs/op`). The `goos` and `goarch` indicate the operating system and architecture where the benchmark was executed.
goos: darwin
goarch: amd64
pkg: your_package_name
cpu: Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz
BenchmarkFibonacci10-12 1708552 686.3 ns/op 0 B/op 0 allocs/op
PASS
ok your_package_name 1.396s
Concepts Behind the Snippet
Go's benchmarking framework is built into the `testing` package, making it easy to measure the performance of your code. The framework provides tools to control the number of iterations and report detailed statistics about execution time and memory usage. Understanding these statistics helps identify areas for optimization.
Real-Life Use Case
Consider a web server that processes a large number of requests. Benchmarking the request handling functions can help identify bottlenecks and optimize the server's performance. For example, you might benchmark different algorithms for processing incoming data or different data structures for storing session information. Benchmarking data serialization/deserialization or database access operations is also very common.
Best Practices
Interview Tip
Be prepared to discuss the purpose of benchmarking, how to write a basic benchmark function, and how to interpret the results. Understanding common performance metrics like time per operation, memory allocation, and the number of allocations is crucial. Be able to explain the difference between profiling and benchmarking.
When to Use Benchmarks
Use benchmarks when you need to optimize the performance of critical sections of your code. This is especially useful when comparing different algorithms or implementations. Benchmarks are also valuable for detecting performance regressions during development and for ensuring that changes don't negatively impact performance.
Memory Footprint
The `-benchmem` flag is useful for understanding the memory footprint of your code. Reducing memory allocations can often improve performance, especially in garbage-collected languages like Go. Consider using techniques like object pooling or pre-allocating memory to reduce allocations.
Alternatives
Pros
Cons
FAQ
-
How do I exclude certain benchmarks from running?
You can use the `-bench` flag with a regular expression to specify which benchmarks to run. For example, `go test -bench=Fibonacci` will only run benchmarks that contain the word 'Fibonacci'. -
Can I run benchmarks in parallel?
Yes, you can use the `b.RunParallel` method to run benchmarks in parallel. This is useful for measuring the performance of concurrent code. -
How do I reset the timer in a benchmark?
Use `b.ResetTimer()` to reset the timer before starting the code you want to benchmark. This is useful for excluding setup code from the timing measurements.