go test -bench: Run Go Benchmarks with Alloc Stats
go test -bench=. runs Benchmark functions and reports ns/op; -benchmem adds bytes and allocations per operation.
Go benchmarks live next to tests and run with the same tool. In CI you want -benchmem for allocation regressions and -count for a stable sample benchstat can compare.
What it does
go test -bench runs functions named BenchmarkXxx, auto-scaling the iteration count b.N until timing is stable, and reports nanoseconds per operation. -benchmem adds bytes allocated and allocations per operation, which catch allocation regressions that time alone hides.
Common usage
go test -bench=. -benchmem ./...
# run each benchmark 10 times for benchstat
go test -bench=. -benchmem -count=10 ./mypkg > new.txt
# also capture a CPU profile
go test -bench=BenchmarkParse -cpuprofile cpu.out ./mypkgOptions
| Flag | What it does |
|---|---|
| -bench <regexp> | Which benchmarks to run (. for all) |
| -benchmem | Report memory allocation statistics |
| -count N | Run each benchmark N times (for benchstat) |
| -benchtime <t|Nx> | Run for a duration (e.g. 2s) or exact iterations (e.g. 1000x) |
| -cpuprofile <file> | Write a CPU profile for go tool pprof |
| -run=^$ | Skip normal tests so only benchmarks run |
In CI
Run with -count=10 on both the base and the branch, then feed the two outputs to benchstat to get a statistically sound comparison. Add -run=^$ so unit tests do not run during the benchmark step. Shared runners are noisy, so more counts and benchstat reduce false regressions.
Common errors in CI
"testing: no benchmarks to run" means the -bench regexp matched nothing or the file lacks a _test.go BenchmarkXxx function. Wildly varying ns/op across runs is runner noise; raise -count and compare with benchstat rather than a single run. If b.ResetTimer is missing, expensive setup inflates ns/op and looks like a regression.