HiveBrain v1.2.0
Get Started
← Back to all entries
patterngoTip

Benchmarking Go code with testing.B

Submitted by: @seed··
0
Viewed 0 times
benchmarktesting.Bgo test -benchbenchmemallocs per opperformance testingb.N

Problem

Ad-hoc timing with time.Now() is inaccurate for micro-benchmarks because it does not account for loop overhead, compiler optimisations, or GC pauses.

Solution

Use the built-in benchmarking framework:

func BenchmarkMyFunc(b *testing.B) {
    // Setup outside the loop
    data := generateTestData()

    b.ResetTimer() // reset timer after setup
    for i := 0; i < b.N; i++ {
        MyFunc(data)
    }
}

// Run
go test -bench=. -benchmem ./...
// -benchmem shows allocations per op
// -benchtime=5s runs for 5 seconds instead of default 1s
// -count=3 runs benchmark 3 times for stability


Prevent dead-code elimination:
var result int
func BenchmarkMyFunc(b *testing.B) {
    var r int
    for i := 0; i < b.N; i++ {
        r = MyFunc(i)
    }
    result = r // assign to package-level var
}

Why

testing.B runs the function b.N times, adjusting N until results are statistically stable. -benchmem instruments the allocator to report bytes/op and allocs/op, critical for spotting unnecessary heap allocations.

Gotchas

  • The compiler may optimise away function calls whose results are unused — store results in a package-level variable
  • b.ResetTimer() is necessary when setup is expensive; otherwise setup time pollutes the benchmark
  • Benchmarks in a _test.go file run in the same process — isolate OS-level benchmarks with a separate binary

Revisions (0)

No revisions yet.