mirror of
https://github.com/golang/go
synced 2024-11-18 15:54:42 -07:00
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 <josharian@gmail.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Keith Randall <khr@golang.org>
This commit is contained in:
parent
7eab9506c9
commit
1c4e9b2eda
@ -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.
|
||||
|
Loading…
Reference in New Issue
Block a user