bytes, strings: micro-optimize EqualFold

The first loop leaves the lengths of the two arguments unchanged.

Take advantage of this invariant in the loop's condition. Here are some
benchmark results (no change to allocations):

goos: darwin
goarch: amd64
pkg: strings
cpu: Intel(R) Core(TM) i7-6700HQ CPU @ 2.60GHz
                          │     old     │                new                 │
                          │   sec/op    │   sec/op     vs base               │
EqualFold/Tests-8           240.0n ± 4%   245.1n ± 5%       ~ (p=0.516 n=20)
EqualFold/ASCII-8           11.50n ± 1%   11.04n ± 0%  -3.96% (p=0.000 n=20)
EqualFold/UnicodePrefix-8   102.1n ± 0%   102.2n ± 0%       ~ (p=0.455 n=20)
EqualFold/UnicodeSuffix-8   90.14n ± 0%   89.80n ± 1%       ~ (p=0.113 n=20)
geomean                     71.00n        70.60n       -0.56%

Change-Id: I1f6d1df8a0398f9493692f59d7369c3f0fbba436
GitHub-Last-Rev: 9508ee26ad
GitHub-Pull-Request: golang/go#73672
Reviewed-on: https://go-review.googlesource.com/c/go/+/671756
Reviewed-by: Michael Knyszek <mknyszek@google.com>
Reviewed-by: Keith Randall <khr@golang.org>
Reviewed-by: Keith Randall <khr@google.com>
Auto-Submit: Keith Randall <khr@golang.org>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
This commit is contained in:
Julien Cretel 2025-05-12 12:40:36 +00:00 committed by Gopher Robot
parent c57b0d6c7e
commit c0eb7ab306
2 changed files with 2 additions and 2 deletions

View File

@ -1228,7 +1228,7 @@ func ReplaceAll(s, old, new []byte) []byte {
func EqualFold(s, t []byte) bool {
// ASCII fast path
i := 0
for ; i < len(s) && i < len(t); i++ {
for n := min(len(s), len(t)); i < n; i++ {
sr := s[i]
tr := t[i]
if sr|tr >= utf8.RuneSelf {

View File

@ -1194,7 +1194,7 @@ func ReplaceAll(s, old, new string) string {
func EqualFold(s, t string) bool {
// ASCII fast path
i := 0
for ; i < len(s) && i < len(t); i++ {
for n := min(len(s), len(t)); i < n; i++ {
sr := s[i]
tr := t[i]
if sr|tr >= utf8.RuneSelf {