mirror of
https://github.com/golang/go
synced 2024-11-19 17:14:44 -07:00
reflect: fix FieldByNameFunc
The existing algorithm did not properly propagate the type count from one level to the next, and as a consequence it missed collisions. Properly propagate multiplicity (count) information to the next level. benchmark old ns/op new ns/op delta BenchmarkFieldByName1 182 180 -1.10% BenchmarkFieldByName2 6273 6183 -1.43% BenchmarkFieldByName3 49267 46784 -5.04% Fixes #4355. R=rsc CC=golang-dev https://golang.org/cl/6821094
This commit is contained in:
parent
2e77bc48aa
commit
aa38801788
@ -1694,6 +1694,20 @@ type S13 struct {
|
||||
S8
|
||||
}
|
||||
|
||||
// The X in S15.S11.S1 and S16.S11.S1 annihilate.
|
||||
type S14 struct {
|
||||
S15
|
||||
S16
|
||||
}
|
||||
|
||||
type S15 struct {
|
||||
S11
|
||||
}
|
||||
|
||||
type S16 struct {
|
||||
S11
|
||||
}
|
||||
|
||||
var fieldTests = []FTest{
|
||||
{struct{}{}, "", nil, 0},
|
||||
{struct{}{}, "Foo", nil, 0},
|
||||
@ -1719,6 +1733,7 @@ var fieldTests = []FTest{
|
||||
{S5{}, "Y", []int{2, 0, 1}, 0},
|
||||
{S10{}, "X", nil, 0},
|
||||
{S10{}, "Y", []int{2, 0, 0, 1}, 0},
|
||||
{S14{}, "X", nil, 0},
|
||||
}
|
||||
|
||||
func TestFieldByIndex(t *testing.T) {
|
||||
|
@ -913,19 +913,22 @@ func (t *structType) FieldByNameFunc(match func(string) bool) (result StructFiel
|
||||
|
||||
// Queue embedded struct fields for processing with next level,
|
||||
// but only if we haven't seen a match yet at this level and only
|
||||
// if the embedded types haven't alredy been queued.
|
||||
// if the embedded types haven't already been queued.
|
||||
if ok || ntyp == nil || ntyp.Kind() != Struct {
|
||||
continue
|
||||
}
|
||||
styp := (*structType)(unsafe.Pointer(ntyp))
|
||||
if nextCount[styp] > 0 {
|
||||
nextCount[styp]++
|
||||
nextCount[styp] = 2 // exact multiple doesn't matter
|
||||
continue
|
||||
}
|
||||
if nextCount == nil {
|
||||
nextCount = map[*structType]int{}
|
||||
}
|
||||
nextCount[styp] = 1
|
||||
if count[t] > 1 {
|
||||
nextCount[styp] = 2 // exact multiple doesn't matter
|
||||
}
|
||||
var index []int
|
||||
index = append(index, scan.index...)
|
||||
index = append(index, i)
|
||||
|
Loading…
Reference in New Issue
Block a user