runtime: add AddCleanup benchmark

Change-Id: Ia463a9b3b5980670bcf9297b4bddb60980ebfde5
Reviewed-on: https://go-review.googlesource.com/c/go/+/720320
Auto-Submit: Michael Knyszek <mknyszek@google.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Carlos Amedee <carlos@golang.org>
This commit is contained in:
Michael Anthony Knyszek 2025-11-13 17:17:35 +00:00 committed by Gopher Robot
parent 80c91eedbb
commit 9fd2e44439

View file

@ -336,3 +336,31 @@ func TestCleanupLost(t *testing.T) {
t.Errorf("expected %d cleanups to be executed, got %d", got, want) t.Errorf("expected %d cleanups to be executed, got %d", got, want)
} }
} }
// BenchmarkAddCleanupAndStop benchmarks adding and removing a cleanup
// from the same allocation.
//
// At face value, this benchmark is unrealistic, since no program would
// do this in practice. However, adding cleanups to new allocations in a
// loop is also unrealistic. It adds additional unused allocations,
// exercises uncommon performance pitfalls in AddCleanup (traversing the
// specials list, which should just be its own benchmark), and executing
// cleanups at a frequency that is unlikely to appear in real programs.
//
// This benchmark is still useful however, since we can get a low-noise
// measurement of the cost of AddCleanup and Stop all in one without the
// above pitfalls: we can measure the pure overhead. We can then separate
// out the cost of each in CPU profiles if we so choose (they're not so
// inexpensive as to make this infeasible).
func BenchmarkAddCleanupAndStop(b *testing.B) {
b.ReportAllocs()
type T struct {
v int
p unsafe.Pointer
}
x := new(T)
for b.Loop() {
runtime.AddCleanup(x, func(int) {}, 14).Stop()
}
}