Skip to content

Migrate b.N benchmark loops to b.Loop() - #5305

Merged
pietern merged 8 commits into
mainfrom
go1.26-b-loop
May 26, 2026
Merged

Migrate b.N benchmark loops to b.Loop()#5305
pietern merged 8 commits into
mainfrom
go1.26-b-loop

Conversation

@pietern

Copy link
Copy Markdown
Contributor

Stacked on top of #5302.

Go 1.26 fixed the inlining regression that made b.Loop() worse than b.N on 1.24/1.25. Migrates the 4 remaining loops and adds a ruleguard rule. Redundant b.ResetTimer()/b.StopTimer() around each loop are removed too.

This pull request and its description were written by Isaac.

pietern added 6 commits May 21, 2026 20:24
Bump Go to `go1.26.0` / `toolchain go1.26.3` across all four modules. This
cleans up an inconsistency: `go.mod`, `tools/task/go.mod`, and
`bundle/internal/tf/codegen/go.mod` were sitting at `go 1.25.8` while
`tools/go.mod` had drifted back to `go 1.25.0`. All four are now in sync.
Release notes: https://go.dev/doc/go1.26
Co-authored-by: Isaac
Bumping the `go` directive to 1.26.0 unlocks two modernize analyzers that
were silent on 1.25:
* stditerators - prefer reflect.Type.Fields()/Methods() and
reflect.Value.Fields()/Methods() over the classic
NumField()/Field(i) loop pattern.
* newexpr - replace local `*T` helpers like `func intPtr(v int) *int
{ return &v }` (and their callers) with Go 1.26's `new(expr)`.
This commit is the verbatim output of `golangci-lint run --fix ./...`,
applied at the same time as the toolchain bump so CI doesn't fail the
moment the bump lands.
A few `field := field` style redeclarations the fixer leaves behind are
harmless (the loop variable is fresh per-iteration since Go 1.22). Leaving
those for a follow-up cleanup rather than expanding the diff here.
Co-authored-by: Isaac
Follow-up to the previous commit, which the previous commit message
deferred. Two cosmetic clean-ups:
1. Remove 14 redundant `x := x` redeclarations the modernize fixer left
inside `for x := range t.Fields()` (or `.Methods()`) loops. The loop
variable is already fresh per-iteration since Go 1.22, so the shadow
was a no-op kept only to preserve the variable name from the old
`field := t.Field(i)` pattern.
2. Remove dead `*Ptr` helper functions whose call sites were inlined to
`new(expr)`. The fixer added `//go:fix inline` directives and rewrote
the bodies to `return new(v)`, leaving the functions themselves with
zero callers (except `int64Ptr`, where `new(700)` would yield `*int`
instead of `*int64`; here we rewrite the 20 callers to
`new(int64(N))` and drop the helper too).
* bundle/docsgen/nodes_test.go: drop strPtr
* libs/apps/runlocal/spec_test.go: drop stringPtr
* libs/structs/structaccess/convert_test.go: drop stringPtr, intPtr,
float64Ptr, boolPtr
* cmd/pipelines/history_test.go: rewrite int64Ptr callers, drop helper
Co-authored-by: Isaac
testing.B.Loop() was added in Go 1.24 with a performance regression that
made it prevent inlining; that was fixed in Go 1.26. There's no longer any
reason to use 'for i := 0; i < b.N; i++' — b.Loop() handles the loop
counter, correct keep-alive semantics, and timer setup automatically.
This commit adds the rule only; lint will fail on existing benchmarks. The
follow-up commit migrates them.
Co-authored-by: Isaac
b.Loop() was added in Go 1.24 but had an inlining regression that's fixed
in Go 1.26. The new form is strictly better: automatic timer setup, correct
keep-alive of the loop body, and inlineable. b.ResetTimer() calls
immediately before the loop are no longer needed.
Co-authored-by: Isaac
@eng-dev-ecosystem-bot

eng-dev-ecosystem-bot commented May 21, 2026

Copy link
Copy Markdown
Collaborator

Commit: ff9c1ad

Run: 26450805938

@denikdenik left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: would be nice to include as a comment output of before and after, since these are manually run.

Base automatically changed from bump-go1.26 to mainMay 21, 2026 20:46
@pietern
pieterntemporarily deployed to test-trigger-is May 22, 2026 07:08 — with GitHub Actions Inactive
@pietern
pieterntemporarily deployed to test-trigger-is May 22, 2026 07:08 — with GitHub Actions Inactive
@pietern

Copy link
Copy Markdown
ContributorAuthor

I ran a before/after manually and there was no meaningful difference.

@pietern
pietern enabled auto-merge May 26, 2026 13:24
@pietern
pieterntemporarily deployed to test-trigger-is May 26, 2026 13:25 — with GitHub Actions Inactive
@pietern
pieterntemporarily deployed to test-trigger-is May 26, 2026 13:25 — with GitHub Actions Inactive
@pietern
pietern added this pull request to the merge queueMay 26, 2026
@pietern
pietern removed this pull request from the merge queue due to a manual request May 26, 2026
@pietern
pietern added this pull request to the merge queueMay 26, 2026
Merged via the queue into main with commit 9486bdfMay 26, 2026
23 checks passed
@pietern
pietern deleted the go1.26-b-loop branch May 26, 2026 14:49
@eng-dev-ecosystem-bot

Copy link
Copy Markdown
Collaborator

Commit: 9486bdf

Run: 26455779124

@eng-dev-ecosystem-bot

Copy link
Copy Markdown
Collaborator

Commit: 9486bdf

Run: 26455888725

denik pushed a commit that referenced this pull request May 28, 2026
Stacked on top of #5302.
Go 1.26 fixed the inlining regression that made `b.Loop()` worse than
`b.N` on 1.24/1.25. Migrates the 4 remaining loops and adds a ruleguard
rule. Redundant `b.ResetTimer()`/`b.StopTimer()` around each loop are
removed too.
This pull request and its description were written by Isaac.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@pietern@eng-dev-ecosystem-bot@denik