From 5029c3671dec0e086fdefbd5a5bb43afa9711905 Mon Sep 17 00:00:00 2001 From: Josh Bleecher Snyder Date: Fri, 24 Apr 2020 09:54:13 -0700 Subject: [PATCH] cmd/compile: improve generated eq algs for structs containing strings 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 TryBot-Result: Gobot Gobot Reviewed-by: Brad Fitzpatrick --- src/cmd/compile/internal/gc/alg.go | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/cmd/compile/internal/gc/alg.go b/src/cmd/compile/internal/gc/alg.go index 1130a4c17bc..33e8eca54e8 100644 --- a/src/cmd/compile/internal/gc/alg.go +++ b/src/cmd/compile/internal/gc/alg.go @@ -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 }