You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
from private mail:
I've noticed that calling reflect.Value's Interface method is slower if the value being
reflected is larger than a word. It appears that this is due to an extra memory alloc,
but it seems like this should only be necessary if the reflect.Value is addressable.
As an example:
type S struct {
i1 int64
i2 int64
}
func BenchmarkInterfaceBig(b *testing.B) {
v := reflect.ValueOf(S{})
for i := 0; i < b.N; i++ {
v.Interface()
}
}
func BenchmarkInterfaceSmall(b *testing.B) {
v := reflect.ValueOf(int64(0))
for i := 0; i < b.N; i++ {
v.Interface()
}
}
BenchmarkInterfaceBig 20000000 84.6 ns/op 16 B/op 1 allocs/op
BenchmarkInterfaceSmall 100000000 23.2 ns/op 0 B/op 0 allocs/op
Since reflect.ValueOf(S{}) isn't addressable, it seems like it shouldn't have to do an
alloc. I took a look src/pkg/reflect/value.go and it seems that it allocs for the
following case (line 953 on tip):
if v.flag&flagIndir != 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.
ptr := unsafe_New(v.typ)
memmove(ptr, unsafe.Pointer(eface.word), v.typ.size)
eface.word = iword(ptr)
}
Should "v.flag&flagIndir != 0" instead be "v.flag&flagAddr !=
0"? I might be misinterpreting this code, but it seems like we can reuse the data
if it's not addressable.
The text was updated successfully, but these errors were encountered:
The text was updated successfully, but these errors were encountered: