]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: improve generated eq algs for structs containing strings
authorJosh Bleecher Snyder <josharian@gmail.com>
Fri, 24 Apr 2020 16:54:13 +0000 (09:54 -0700)
committerJosh Bleecher Snyder <josharian@gmail.com>
Mon, 27 Apr 2020 17:19:16 +0000 (17:19 +0000)
type T struct {
    s string
    i int
}

Prior to this change, we generated this equality algorithm for T:

func eqT(p, q *T) bool {
    return len(p.s) == len(q.s) &&
      runtime.memequal(p.s.ptr, q.s.ptr, len(p.s)) &&
      p.i == q.i
}

This change splits the two halves of the string equality,
so that we can do the cheap (length) half early and the expensive
(contents) half late. We now generate:

func eqT(p, q *T) bool {
    return len(p.s) == len(q.s) &&
      p.i == q.i &&
      runtime.memequal(p.s.ptr, q.s.ptr, len(p.s))
}

The generated code for these functions tends to be a bit shorter. Examples:

runtime
.eq."".Frame 274 -> 272  (-0.73%)
.eq."".funcinl 249 -> 247  (-0.80%)
.eq."".modulehash 207 -> 205  (-0.97%)

Change-Id: I4efac9f7d410f0a11a94dcee2bf9c0b49b60e301
Reviewed-on: https://go-review.googlesource.com/c/go/+/230205
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
src/cmd/compile/internal/gc/alg.go

index 1130a4c17bc9b3add6d1ff6a6ae86f1b85d50bad..33e8eca54e88f9194b9db88940dec087f92e234d 100644 (file)
@@ -578,7 +578,16 @@ func geneq(t *types.Type) *obj.LSym {
 
                        // Compare non-memory fields with field equality.
                        if !IsRegularMemory(f.Type) {
-                               and(eqfield(np, nq, f.Sym))
+                               p := nodSym(OXDOT, np, f.Sym)
+                               q := nodSym(OXDOT, nq, f.Sym)
+                               switch {
+                               case f.Type.IsString():
+                                       eqlen, eqmem := eqstring(p, q)
+                                       and(eqlen)
+                                       and(eqmem)
+                               default:
+                                       and(nod(OEQ, p, q))
+                               }
                                i++
                                continue
                        }