mirror of
https://github.com/golang/go
synced 2024-11-26 03:27:58 -07:00
reflect: avoid allocation when interface's contents are not addressable
See issue 4949 for a full explanation. Allocs go from 1 to zero in the non-addressable case. Fixes #4949. BenchmarkInterfaceBig 90 14 -84.01% BenchmarkInterfaceSmall 14 14 +0.00% R=golang-dev, bradfitz CC=golang-dev https://golang.org/cl/12646043
This commit is contained in:
parent
d2bff757f6
commit
94179d61ab
@ -3419,6 +3419,40 @@ func BenchmarkFieldByName3(b *testing.B) {
|
||||
}
|
||||
}
|
||||
|
||||
type S struct {
|
||||
i1 int64
|
||||
i2 int64
|
||||
}
|
||||
|
||||
func BenchmarkInterfaceBig(b *testing.B) {
|
||||
v := ValueOf(S{})
|
||||
for i := 0; i < b.N; i++ {
|
||||
v.Interface()
|
||||
}
|
||||
b.StopTimer()
|
||||
}
|
||||
|
||||
func TestAllocsInterfaceBig(t *testing.T) {
|
||||
v := ValueOf(S{})
|
||||
if allocs := testing.AllocsPerRun(100, func() { v.Interface() }); allocs > 0 {
|
||||
t.Errorf("allocs:", allocs)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkInterfaceSmall(b *testing.B) {
|
||||
v := ValueOf(int64(0))
|
||||
for i := 0; i < b.N; i++ {
|
||||
v.Interface()
|
||||
}
|
||||
}
|
||||
|
||||
func TestAllocsInterfaceSmall(t *testing.T) {
|
||||
v := ValueOf(int64(0))
|
||||
if allocs := testing.AllocsPerRun(100, func() { v.Interface() }); allocs > 0 {
|
||||
t.Errorf("allocs:", allocs)
|
||||
}
|
||||
}
|
||||
|
||||
// An exhaustive is a mechanism for writing exhaustive or stochastic tests.
|
||||
// The basic usage is:
|
||||
//
|
||||
|
@ -1004,7 +1004,8 @@ func valueInterface(v Value, safe bool) interface{} {
|
||||
eface.typ = v.typ
|
||||
eface.word = v.iword()
|
||||
|
||||
if v.flag&flagIndir != 0 && v.typ.size > ptrSize {
|
||||
// Don't need to allocate if v is not addressable or fits in one word.
|
||||
if v.flag&flagAddr != 0 && v.typ.size > ptrSize {
|
||||
// eface.word is a pointer to the actual data,
|
||||
// which might be changed. We need to return
|
||||
// a pointer to unchanging data, so make a copy.
|
||||
|
Loading…
Reference in New Issue
Block a user