cmd/compile/internal/test: add benchmark for string comparison operand order

Add BenchmarkStringEqParamOrder to verify that the operand order of
string equality comparisons (strs[i] == str vs str == strs[i]) does not
affect performance when the comparand is a function parameter.

This benchmark was written while investigating issue #74471. Extensive
benchmarking on both amd64 (Intel Xeon Gold 6148, linux) and arm64
(Apple M1 Pro, darwin) with 30 samples each showed that on Go tip the
compiler already generates equivalent code for both orderings, so no
compiler change is needed. The benchmark is retained as a regression
guard.

Updates #74471

Change-Id: I257910bba0abb3dc738578d898e63ecfb261c3cc
Reviewed-on: https://go-review.googlesource.com/c/go/+/742141
Reviewed-by: Keith Randall <khr@google.com>
Auto-Submit: Keith Randall <khr@golang.org>
Reviewed-by: David Chase <drchase@google.com>
Reviewed-by: Keith Randall <khr@golang.org>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
This commit is contained in:
yongqijia
2026-02-12 11:35:18 +08:00
committed by Gopher Robot
parent 83b4c5d233
commit c4de16a714

View File

@@ -4,7 +4,10 @@
package test
import "testing"
import (
"fmt"
"testing"
)
var globl int64
var globl32 int32
@@ -174,3 +177,53 @@ func BenchmarkSimplifyNegDiv(b *testing.B) {
globl = s
}
}
var globbool bool
// containsRight compares strs[i] == str (slice element on left).
//
//go:noinline
func containsRight(strs []string, str string) bool {
for i := range strs {
if strs[i] == str {
return true
}
}
return false
}
// containsLeft compares str == strs[i] (parameter on left).
//
//go:noinline
func containsLeft(strs []string, str string) bool {
for i := range strs {
if str == strs[i] {
return true
}
}
return false
}
// BenchmarkStringEqParamOrder tests that the operand order of string
// equality comparisons does not affect performance. See issue #74471.
func BenchmarkStringEqParamOrder(b *testing.B) {
strs := []string{
"12312312", "abcsdsfw", "abcdefgh", "qereqwre",
"gwertdsg", "hellowod", "iamgroot", "theiswer",
"dg323sdf", "gadsewwe", "g42dg4t3", "4hre2323",
"23eg4325", "13234234", "32dfgsdg", "23fgre34",
"43rerrer", "hh2s2443", "hhwesded", "1swdf23d",
"gwcdrwer", "bfgwertd", "badgwe3g", "lhoejyop",
}
target := fmt.Sprintf("%s", "notfound")
b.Run("ParamRight", func(b *testing.B) {
for b.Loop() {
globbool = containsRight(strs, target)
}
})
b.Run("ParamLeft", func(b *testing.B) {
for b.Loop() {
globbool = containsLeft(strs, target)
}
})
}