From: Josh Bleecher Snyder Date: Sat, 25 Apr 2020 22:14:35 +0000 (-0700) Subject: cmd/compile: improve equality algs for arrays of strings X-Git-Tag: go1.15beta1~356 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=1c4e9b2edaa741860944edef83b7ce8eac00079e;p=gostls13.git cmd/compile: improve equality algs for arrays of strings type T [8]string Prior to this change, we generated this equality algorithm for T: func eqT(p, q *T) (r bool) { for i := range *p { if p[i] == q[i] { } else { return } } return true } This change splits this into two loops, so that we can do the cheap (length) half early and only then do the expensive (contents) half. We now generate: func eqT(p, q *T) (r bool) { for i := range *p { if len(p[i]) == len(q[i]) { } else { return } } for j := range *p { if runtime.memeq(p[j].ptr, q[j].ptr, len(p[j])) { } else { return } } return true } The generated code is typically ~17% larger because it contains two loops instead of one. In the future, we might want to unroll the first loop when the array is small. Change-Id: I26b2793b90ec6aff21766a411b15a4ff1096c03f Reviewed-on: https://go-review.googlesource.com/c/go/+/230209 Run-TryBot: Josh Bleecher Snyder TryBot-Result: Gobot Gobot Reviewed-by: Keith Randall --- diff --git a/src/cmd/compile/internal/gc/alg.go b/src/cmd/compile/internal/gc/alg.go index f6291063a0..bda9ab5bff 100644 --- a/src/cmd/compile/internal/gc/alg.go +++ b/src/cmd/compile/internal/gc/alg.go @@ -574,6 +574,20 @@ func geneq(t *types.Type) *obj.LSym { _, eqdata := eqinterface(pi, qi) return eqdata }) + case TSTRING: + // Do two loops. First, check that all the lengths match (cheap). + // Second, check that all the contents match (expensive). + // TODO: when the array size is small, unroll the length match checks. + rangedCheck("i", func(pi, qi *Node) *Node { + // Compare lengths. + eqlen, _ := eqstring(pi, qi) + return eqlen + }) + rangedCheck("j", func(pi, qi *Node) *Node { + // Compare contents. + _, eqmem := eqstring(pi, qi) + return eqmem + }) default: // An array of pure memory would be handled by the standard memequal, // so the element type must not be pure memory.