Skip to content

testing: allocs reported incorrectly depending on the --benchtime and --count flags #75364

@ainar-g

Description

@ainar-g

Go version

go version go1.25.1 linux/amd64

Output of go env in your module/workspace:

AR='ar'
CC='clang'
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_ENABLED='1'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
CXX='clang++'
GCCGO='gccgo'
GO111MODULE=''
GOAMD64='v1'
GOARCH='amd64'
GOAUTH='netrc'
GOBIN=''
GOCACHE='/home/ainar/.cache/go-build'
GOCACHEPROG=''
GODEBUG=''
GOENV='/home/ainar/.config/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFIPS140='off'
GOFLAGS=''
GOGCCFLAGS='-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -Wl,--no-gc-sections -fmessage-length=0 -ffile-prefix-map=/tmp/go-build4247421775=/tmp/go-build -gno-record-gcc-switches'
GOHOSTARCH='amd64'
GOHOSTOS='linux'
GOINSECURE=''
GOMOD='/home/ainar/agrd/urlfilter/go.mod'
GOMODCACHE='/home/ainar/go/pkg/mod'
GONOPROXY='REDACTED'
GONOSUMDB='REDACTED'
GOOS='linux'
GOPATH='/home/ainar/go'
GOPRIVATE='REDACTED'
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/home/ainar/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.25.1.linux-amd64'
GOSUMDB='sum.golang.org'
GOTELEMETRY='local'
GOTELEMETRYDIR='/home/ainar/.config/go/telemetry'
GOTMPDIR=''
GOTOOLCHAIN='go1.25.1'
GOTOOLDIR='/home/ainar/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.25.1.linux-amd64/pkg/tool/linux_amd64'
GOVCS=''
GOVERSION='go1.25.1'
GOWORK=''
PKG_CONFIG='pkg-config'

What did you do?

  1. Checkout github.com/AdguardTeam/urlfilter v0.21.0.
  2. go test --bench='BenchmarkSeqScanTable_AppendMatching_baseFilter' --run='^$' ./internal/lookup/
    go test --bench='BenchmarkSeqScanTable_AppendMatching_baseFilter' --benchtime=10s --run='^$' ./internal/lookup/
    go test --bench='BenchmarkSeqScanTable_AppendMatching_baseFilter' --benchtime=1s --count=10 --run='^$' ./internal/lookup/

What did you see happen?

allocs/op goes between 4 (the first and third call) and 0 (the second call). B/op is also drastically different between them.

If I add --memprofile=mem.out and inspect mem.out with go tool pprof, it point to the code in the benchmark setup. That is, the code that goes before b.ReportAllocs and b.Loop calls, for example loadTable.

What did you expect to see?

Consistent results which only include the allocations from the for b.Loop() body.

Metadata

Metadata

Assignees

No one assigned

    Labels

    BugReportIssues describing a possible bug in the Go implementation.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions