Benchmark Profiling with pprof

One quick and simple way to profile Go code is benchmark test profiling.

Profiling benchmarks is useful for identifying the hot code for a particular functionality, and it is as a part of the application performance tuning process, described in Go Performance Tuning guide.

The following example simulates some CPU work. We will use pprof to locate the hot spots.

package main

import (
	"math/rand"
	"testing"
)

func BenchmarkRand(b *testing.B) {
	for n := 0; n < b.N; n++ {
		rand.Int63()
	}
}

Generating a CPU profile for the benchmark test:

go test -bench=BenchmarkRand -benchmem -cpuprofile profile.out

The -memprofile and -blockprofile flags can be used to generate memory allocation and blocking call profiles.

Analyzing the profile using the Go tool:

go tool pprof profile.out
(pprof) top
Showing nodes accounting for 1.16s, 100% of 1.16s total
Showing top 10 nodes out of 22
      flat  flat%   sum%        cum   cum%
     0.41s 35.34% 35.34%      0.41s 35.34%  sync.(*Mutex).Unlock
     0.37s 31.90% 67.24%      0.37s 31.90%  sync.(*Mutex).Lock
     0.12s 10.34% 77.59%      1.03s 88.79%  math/rand.(*lockedSource).Int63
     0.08s  6.90% 84.48%      0.08s  6.90%  math/rand.(*rngSource).Uint64 (inline)
     0.06s  5.17% 89.66%      1.11s 95.69%  math/rand.Int63
     0.05s  4.31% 93.97%      0.13s 11.21%  math/rand.(*rngSource).Int63
     0.04s  3.45% 97.41%      1.15s 99.14%  benchtest.BenchmarkRand
     0.02s  1.72% 99.14%      1.05s 90.52%  math/rand.(*Rand).Int63
     0.01s  0.86%   100%      0.01s  0.86%  runtime.futex
         0     0%   100%      0.01s  0.86%  runtime.allocm

We can see that, since the default source in math/rand is synchronized, the bottleneck in this case is the mutex.

Other profile presentations and output formats are also possible, e.g. tree. Type help for more options.

Note, any benchmark initialization code (the code before the loop) will also be profiled and may represent a big part of the profile.

To profile a running program in development or production environment, see the Profiling Go Applications in Production Environments blog post.