Performance matters — especially when dealing with large-scale systems or performance-critical code. Go (Golang) provides first-class support for benchmarking via the testing
package. This article walks you through the fundamentals of benchmarking in Go: what it is, why it's important, and how to run benchmarks to compare multiple functions.
🧠 What is Benchmarking?
Benchmarking is the process of measuring how efficiently a piece of code executes. In Go, this typically involves determining how long a function takes to run, how many resources it uses, or how well it scales under load.
Benchmarking is different from testing — it doesn’t check if your code is correct but it checks how well it performs.
✅ Why We Should Do Benchmarking
Benchmarking is useful when you want to:
-
Compare different implementations of the same logic (e.g., using
+
vsstrings.Builder
for string concatenation). - Find performance bottlenecks in your application.
- Track regressions over time, especially in performance-sensitive systems.
- Make data-driven decisions when optimizing code.
In short, benchmarking gives you quantitative insights into your code’s behavior under stress.
💻 Example
Let’s take an easy and real world example which we often overlook
package benchmark
import (
"strings"
"testing"
)
func concatWithPlus(a, b string) string {
return a + b
}
func concatWithBuilder(a, b string) string {
var sb strings.Builder
sb.WriteString(a)
sb.WriteString(b)
return sb.String()
}
func BenchmarkConcatWithPlus(b *testing.B) {
for i := 0; i < b.N; i++ {
_ = concatWithPlus("Hello", "World")
}
}
func BenchmarkConcatWithBuilder(b *testing.B) {
for i := 0; i < b.N; i++ {
_ = concatWithBuilder("Hello", "World")
}
}
▶️ Running the Benchmark
Save the file as concat_test.go
and run:
go test -bench=.
📤 Output
Example output might look like:
goos: linux
goarch: amd64
BenchmarkConcatWithPlus-8 10000000 150 ns/op
BenchmarkConcatWithBuilder-8 20000000 90 ns/op
PASS
ok example.com/benchmark 2.345s
📖 How to Read the Output
Each line shows:
Field | Meaning |
---|---|
BenchmarkConcatWithPlus-8 |
Benchmark function run on 8 logical CPUs |
10000000 |
Number of iterations Go used for benchmarking |
150 ns/op |
Average time taken for one operation (in nanoseconds) |
In this case:
-
concatWithBuilder
is faster (90 ns/op) thanconcatWithPlus
(150 ns/op). - Therefore,
strings.Builder
is a more efficient way to concatenate strings in this context.
Optional Memory Metrics
To view memory allocations and usage:
go test -bench=. -benchmem
Sample output:
BenchmarkConcatWithPlus-8 10000000 150 ns/op 16 B/op 1 allocs/op
BenchmarkConcatWithBuilder-8 20000000 90 ns/op 0 B/op 0 allocs/op
Field | Meaning |
---|---|
150 ns/op |
How many bytes of memory were allocated per iteration. |
1 allocs/op |
How many memory allocation events occurred per iteration. |
This shows:
-
concatWithPlus
allocates memory (16 bytes per operation). -
concatWithBuilder
avoids allocations — a big win for performance.
🏁 Conclusion
Benchmarking in Go is easy to set up and incredibly valuable. It helps you:
- Understand the performance characteristics of your code
- Choose the most efficient implementations
- Catch regressions before they ship to production
By comparing two simple functions, we saw how small differences in implementation can lead to measurable performance improvements.
Top comments (0)