Open
Description
Go version
go 1.24.1
darwin/arm64
Apple M1
Summary
I'm working on a performance optimization in our business logic and noticed a significant performance difference when swapping the strings on either side of an equality operator. After simplifying the logic to a contains
function, I was able to reproduce the behavior. Below are the sample code and benchmarks
Sample Code
var containsSlice = func() []string {
return []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",
}
}()
func containsStringA(strs []string, str string) bool {
for i := range strs {
if strs[i] == str {
return true
}
}
return false
}
func containsStringB(strs []string, str string) bool {
for i := range strs {
if str == strs[i] {
return true
}
}
return false
}
func BenchmarkContainsStringA(b *testing.B) {
for n := 0; n <= b.N; n++ {
containsStringA(containsSlice, "lhoejyop")
}
}
func BenchmarkContainsStringB(b *testing.B) {
for n := 0; n <= b.N; n++ {
containsStringB(containsSlice, "lhoejyop")
}
}
Benchmark Result
goos: darwin
goarch: arm64
pkg: go-playground/simple
cpu: Apple M1
BenchmarkContainsStringA-8 19314198 61.63 ns/op
BenchmarkContainsStringB-8 72874310 16.04 ns/op
Swapping the string comparison order (strs[i] == str ➔ str == strs[i]) results in ~4x performance improvement (61.63 ns/op → 16.04 ns/op)
Why does operand ordering cause performance divergence when both implementations are logically equivalent?