}
}
-func BenchmarkDeepEqual(b *testing.B) {
- for _, bb := range deepEqualPerfTests {
- b.Run(ValueOf(bb.x).Type().String(), func(b *testing.B) {
- b.ReportAllocs()
- for i := 0; i < b.N; i++ {
- sink = DeepEqual(bb.x, bb.y)
- }
- })
- }
-}
-
func check2ndField(x any, offs uintptr, t *testing.T) {
s := ValueOf(x)
f := s.Type().Field(1)
}()
}
-func BenchmarkIsZero(b *testing.B) {
- source := ValueOf(struct {
- ArrayComparable [4]T
- ArrayIncomparable [4]_Complex
- StructComparable T
- StructIncomparable _Complex
- }{})
-
- for i := 0; i < source.NumField(); i++ {
- name := source.Type().Field(i).Name
- value := source.Field(i)
- b.Run(name, func(b *testing.B) {
- for i := 0; i < b.N; i++ {
- sink = value.IsZero()
- }
- })
- }
-}
-
-func BenchmarkSetZero(b *testing.B) {
- source := ValueOf(new(struct {
- Bool bool
- Int int64
- Uint uint64
- Float float64
- Complex complex128
- Array [4]Value
- Chan chan Value
- Func func() Value
- Interface interface{ String() string }
- Map map[string]Value
- Pointer *Value
- Slice []Value
- String string
- Struct Value
- })).Elem()
-
- for i := 0; i < source.NumField(); i++ {
- name := source.Type().Field(i).Name
- value := source.Field(i)
- zero := Zero(value.Type())
- b.Run(name+"/Direct", func(b *testing.B) {
- for i := 0; i < b.N; i++ {
- value.SetZero()
- }
- })
- b.Run(name+"/CachedZero", func(b *testing.B) {
- for i := 0; i < b.N; i++ {
- value.Set(zero)
- }
- })
- b.Run(name+"/NewZero", func(b *testing.B) {
- for i := 0; i < b.N; i++ {
- value.Set(Zero(value.Type()))
- }
- })
- }
-}
-
func TestInterfaceExtraction(t *testing.T) {
var s struct {
W io.Writer
}
}
-func BenchmarkSelect(b *testing.B) {
- channel := make(chan int)
- close(channel)
- var cases []SelectCase
- for i := 0; i < 8; i++ {
- cases = append(cases, SelectCase{
- Dir: SelectRecv,
- Chan: ValueOf(channel),
- })
- }
- for _, numCases := range []int{1, 4, 8} {
- b.Run(strconv.Itoa(numCases), func(b *testing.B) {
- b.ReportAllocs()
- for i := 0; i < b.N; i++ {
- _, _, _ = Select(cases[:numCases])
- }
- })
- }
-}
-
// selectWatch and the selectWatcher are a watchdog mechanism for running Select.
// If the selectWatcher notices that the select has been blocked for >1 second, it prints
// an error describing the select and panics the entire test binary.
runtime.KeepAlive(v)
}
-func BenchmarkCall(b *testing.B) {
- fv := ValueOf(func(a, b string) {})
- b.ReportAllocs()
- b.RunParallel(func(pb *testing.PB) {
- args := []Value{ValueOf("a"), ValueOf("b")}
- for pb.Next() {
- fv.Call(args)
- }
- })
-}
-
-type myint int64
-
-func (i *myint) inc() {
- *i = *i + 1
-}
-
-func BenchmarkCallMethod(b *testing.B) {
- b.ReportAllocs()
- z := new(myint)
-
- v := ValueOf(z.inc)
- for i := 0; i < b.N; i++ {
- v.Call(nil)
- }
-}
-
-func BenchmarkCallArgCopy(b *testing.B) {
- byteArray := func(n int) Value {
- return Zero(ArrayOf(n, TypeOf(byte(0))))
- }
- sizes := [...]struct {
- fv Value
- arg Value
- }{
- {ValueOf(func(a [128]byte) {}), byteArray(128)},
- {ValueOf(func(a [256]byte) {}), byteArray(256)},
- {ValueOf(func(a [1024]byte) {}), byteArray(1024)},
- {ValueOf(func(a [4096]byte) {}), byteArray(4096)},
- {ValueOf(func(a [65536]byte) {}), byteArray(65536)},
- }
- for _, size := range sizes {
- bench := func(b *testing.B) {
- args := []Value{size.arg}
- b.SetBytes(int64(size.arg.Len()))
- b.ResetTimer()
- b.RunParallel(func(pb *testing.PB) {
- for pb.Next() {
- size.fv.Call(args)
- }
- })
- }
- name := fmt.Sprintf("size=%v", size.arg.Len())
- b.Run(name, bench)
- }
-}
-
func TestMakeFunc(t *testing.T) {
f := dummy
fv := MakeFunc(TypeOf(f), func(in []Value) []Value { return in })
}
}
-func BenchmarkPtrTo(b *testing.B) {
- // Construct a type with a zero ptrToThis.
- type T struct{ int }
- t := SliceOf(TypeOf(T{}))
- ptrToThis := ValueOf(t).Elem().FieldByName("ptrToThis")
- if !ptrToThis.IsValid() {
- b.Fatalf("%v has no ptrToThis field; was it removed from rtype?", t)
- }
- if ptrToThis.Int() != 0 {
- b.Fatalf("%v.ptrToThis unexpectedly nonzero", t)
- }
- b.ResetTimer()
-
- // Now benchmark calling PointerTo on it: we'll have to hit the ptrMap cache on
- // every call.
- b.RunParallel(func(pb *testing.PB) {
- for pb.Next() {
- PointerTo(t)
- }
- })
-}
-
func TestAddr(t *testing.T) {
var p struct {
X, Y int
FuncOf(in, nil, false)
}
-type B1 struct {
- X int
- Y int
- Z int
-}
-
-func BenchmarkFieldByName1(b *testing.B) {
- t := TypeOf(B1{})
- b.RunParallel(func(pb *testing.PB) {
- for pb.Next() {
- t.FieldByName("Z")
- }
- })
-}
-
-func BenchmarkFieldByName2(b *testing.B) {
- t := TypeOf(S3{})
- b.RunParallel(func(pb *testing.PB) {
- for pb.Next() {
- t.FieldByName("B")
- }
- })
-}
-
type R0 struct {
*R1
*R2
}
}
-func BenchmarkFieldByName3(b *testing.B) {
- t := TypeOf(R0{})
- b.RunParallel(func(pb *testing.PB) {
- for pb.Next() {
- t.FieldByName("X")
- }
- })
-}
-
-type S struct {
- i1 int64
- i2 int64
-}
-
-func BenchmarkInterfaceBig(b *testing.B) {
- v := ValueOf(S{})
- b.RunParallel(func(pb *testing.PB) {
- for pb.Next() {
- v.Interface()
- }
- })
- b.StopTimer()
-}
-
func TestAllocsInterfaceBig(t *testing.T) {
if testing.Short() {
t.Skip("skipping malloc count in short mode")
}
}
-func BenchmarkInterfaceSmall(b *testing.B) {
- v := ValueOf(int64(0))
- b.RunParallel(func(pb *testing.PB) {
- for pb.Next() {
- v.Interface()
- }
- })
-}
-
func TestAllocsInterfaceSmall(t *testing.T) {
if testing.Short() {
t.Skip("skipping malloc count in short mode")
wg.Wait()
}
-func BenchmarkNew(b *testing.B) {
- v := TypeOf(XM{})
- b.RunParallel(func(pb *testing.PB) {
- for pb.Next() {
- New(v)
- }
- })
-}
-
-func BenchmarkMap(b *testing.B) {
- type V *int
- type S string
- value := ValueOf((V)(nil))
- stringKeys := []string{}
- mapOfStrings := map[string]V{}
- uint64Keys := []uint64{}
- mapOfUint64s := map[uint64]V{}
- userStringKeys := []S{}
- mapOfUserStrings := map[S]V{}
- for i := 0; i < 100; i++ {
- stringKey := fmt.Sprintf("key%d", i)
- stringKeys = append(stringKeys, stringKey)
- mapOfStrings[stringKey] = nil
-
- uint64Key := uint64(i)
- uint64Keys = append(uint64Keys, uint64Key)
- mapOfUint64s[uint64Key] = nil
-
- userStringKey := S(fmt.Sprintf("key%d", i))
- userStringKeys = append(userStringKeys, userStringKey)
- mapOfUserStrings[userStringKey] = nil
- }
-
- tests := []struct {
- label string
- m, keys, value Value
- }{
- {"StringKeys", ValueOf(mapOfStrings), ValueOf(stringKeys), value},
- {"Uint64Keys", ValueOf(mapOfUint64s), ValueOf(uint64Keys), value},
- {"UserStringKeys", ValueOf(mapOfUserStrings), ValueOf(userStringKeys), value},
- }
-
- for _, tt := range tests {
- b.Run(tt.label, func(b *testing.B) {
- b.Run("MapIndex", func(b *testing.B) {
- b.ReportAllocs()
- for i := 0; i < b.N; i++ {
- for j := tt.keys.Len() - 1; j >= 0; j-- {
- tt.m.MapIndex(tt.keys.Index(j))
- }
- }
- })
- b.Run("SetMapIndex", func(b *testing.B) {
- b.ReportAllocs()
- for i := 0; i < b.N; i++ {
- for j := tt.keys.Len() - 1; j >= 0; j-- {
- tt.m.SetMapIndex(tt.keys.Index(j), tt.value)
- }
- }
- })
- })
- }
-}
-
func TestSwapper(t *testing.T) {
type I int
var a, b, c I
}
}
-func BenchmarkMapIterNext(b *testing.B) {
- m := ValueOf(map[string]int{"a": 0, "b": 1, "c": 2, "d": 3})
- it := m.MapRange()
- for i := 0; i < b.N; i++ {
- for it.Next() {
- }
- it.Reset(m)
- }
-}
-
func TestMapIterDelete0(t *testing.T) {
// Delete all elements before first iteration.
m := map[string]int{"one": 1, "two": 2, "three": 3}
namedBytes []byte
)
-var sourceAll = struct {
- Bool Value
- String Value
- Bytes Value
- NamedBytes Value
- BytesArray Value
- SliceAny Value
- MapStringAny Value
-}{
- Bool: ValueOf(new(bool)).Elem(),
- String: ValueOf(new(string)).Elem(),
- Bytes: ValueOf(new([]byte)).Elem(),
- NamedBytes: ValueOf(new(namedBytes)).Elem(),
- BytesArray: ValueOf(new([32]byte)).Elem(),
- SliceAny: ValueOf(new([]any)).Elem(),
- MapStringAny: ValueOf(new(map[string]any)).Elem(),
-}
-
-var sinkAll struct {
- RawBool bool
- RawString string
- RawBytes []byte
- RawInt int
-}
-
-func BenchmarkBool(b *testing.B) {
- for i := 0; i < b.N; i++ {
- sinkAll.RawBool = sourceAll.Bool.Bool()
- }
-}
-
-func BenchmarkString(b *testing.B) {
- for i := 0; i < b.N; i++ {
- sinkAll.RawString = sourceAll.String.String()
- }
-}
-
-func BenchmarkBytes(b *testing.B) {
- for i := 0; i < b.N; i++ {
- sinkAll.RawBytes = sourceAll.Bytes.Bytes()
- }
-}
-
-func BenchmarkNamedBytes(b *testing.B) {
- for i := 0; i < b.N; i++ {
- sinkAll.RawBytes = sourceAll.NamedBytes.Bytes()
- }
-}
-
-func BenchmarkBytesArray(b *testing.B) {
- for i := 0; i < b.N; i++ {
- sinkAll.RawBytes = sourceAll.BytesArray.Bytes()
- }
-}
-
-func BenchmarkSliceLen(b *testing.B) {
- for i := 0; i < b.N; i++ {
- sinkAll.RawInt = sourceAll.SliceAny.Len()
- }
-}
-
-func BenchmarkMapLen(b *testing.B) {
- for i := 0; i < b.N; i++ {
- sinkAll.RawInt = sourceAll.MapStringAny.Len()
- }
-}
-
-func BenchmarkStringLen(b *testing.B) {
- for i := 0; i < b.N; i++ {
- sinkAll.RawInt = sourceAll.String.Len()
- }
-}
-
-func BenchmarkArrayLen(b *testing.B) {
- for i := 0; i < b.N; i++ {
- sinkAll.RawInt = sourceAll.BytesArray.Len()
- }
-}
-
-func BenchmarkSliceCap(b *testing.B) {
- for i := 0; i < b.N; i++ {
- sinkAll.RawInt = sourceAll.SliceAny.Cap()
- }
-}
-
func TestValue_Cap(t *testing.T) {
a := &[3]int{1, 2, 3}
v := ValueOf(a)
--- /dev/null
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package reflect_test
+
+import (
+ "fmt"
+ . "reflect"
+ "strconv"
+ "testing"
+)
+
+var sourceAll = struct {
+ Bool Value
+ String Value
+ Bytes Value
+ NamedBytes Value
+ BytesArray Value
+ SliceAny Value
+ MapStringAny Value
+}{
+ Bool: ValueOf(new(bool)).Elem(),
+ String: ValueOf(new(string)).Elem(),
+ Bytes: ValueOf(new([]byte)).Elem(),
+ NamedBytes: ValueOf(new(namedBytes)).Elem(),
+ BytesArray: ValueOf(new([32]byte)).Elem(),
+ SliceAny: ValueOf(new([]any)).Elem(),
+ MapStringAny: ValueOf(new(map[string]any)).Elem(),
+}
+
+var sinkAll struct {
+ RawBool bool
+ RawString string
+ RawBytes []byte
+ RawInt int
+}
+
+func BenchmarkBool(b *testing.B) {
+ for i := 0; i < b.N; i++ {
+ sinkAll.RawBool = sourceAll.Bool.Bool()
+ }
+}
+
+func BenchmarkString(b *testing.B) {
+ for i := 0; i < b.N; i++ {
+ sinkAll.RawString = sourceAll.String.String()
+ }
+}
+
+func BenchmarkBytes(b *testing.B) {
+ for i := 0; i < b.N; i++ {
+ sinkAll.RawBytes = sourceAll.Bytes.Bytes()
+ }
+}
+
+func BenchmarkNamedBytes(b *testing.B) {
+ for i := 0; i < b.N; i++ {
+ sinkAll.RawBytes = sourceAll.NamedBytes.Bytes()
+ }
+}
+
+func BenchmarkBytesArray(b *testing.B) {
+ for i := 0; i < b.N; i++ {
+ sinkAll.RawBytes = sourceAll.BytesArray.Bytes()
+ }
+}
+
+func BenchmarkSliceLen(b *testing.B) {
+ for i := 0; i < b.N; i++ {
+ sinkAll.RawInt = sourceAll.SliceAny.Len()
+ }
+}
+
+func BenchmarkMapLen(b *testing.B) {
+ for i := 0; i < b.N; i++ {
+ sinkAll.RawInt = sourceAll.MapStringAny.Len()
+ }
+}
+
+func BenchmarkStringLen(b *testing.B) {
+ for i := 0; i < b.N; i++ {
+ sinkAll.RawInt = sourceAll.String.Len()
+ }
+}
+
+func BenchmarkArrayLen(b *testing.B) {
+ for i := 0; i < b.N; i++ {
+ sinkAll.RawInt = sourceAll.BytesArray.Len()
+ }
+}
+
+func BenchmarkSliceCap(b *testing.B) {
+ for i := 0; i < b.N; i++ {
+ sinkAll.RawInt = sourceAll.SliceAny.Cap()
+ }
+}
+
+func BenchmarkDeepEqual(b *testing.B) {
+ for _, bb := range deepEqualPerfTests {
+ b.Run(ValueOf(bb.x).Type().String(), func(b *testing.B) {
+ b.ReportAllocs()
+ for i := 0; i < b.N; i++ {
+ sink = DeepEqual(bb.x, bb.y)
+ }
+ })
+ }
+}
+
+func BenchmarkIsZero(b *testing.B) {
+ source := ValueOf(struct {
+ ArrayComparable [4]T
+ ArrayIncomparable [4]_Complex
+ StructComparable T
+ StructIncomparable _Complex
+ }{})
+
+ for i := 0; i < source.NumField(); i++ {
+ name := source.Type().Field(i).Name
+ value := source.Field(i)
+ b.Run(name, func(b *testing.B) {
+ for i := 0; i < b.N; i++ {
+ sink = value.IsZero()
+ }
+ })
+ }
+}
+
+func BenchmarkSetZero(b *testing.B) {
+ source := ValueOf(new(struct {
+ Bool bool
+ Int int64
+ Uint uint64
+ Float float64
+ Complex complex128
+ Array [4]Value
+ Chan chan Value
+ Func func() Value
+ Interface interface{ String() string }
+ Map map[string]Value
+ Pointer *Value
+ Slice []Value
+ String string
+ Struct Value
+ })).Elem()
+
+ for i := 0; i < source.NumField(); i++ {
+ name := source.Type().Field(i).Name
+ value := source.Field(i)
+ zero := Zero(value.Type())
+ b.Run(name+"/Direct", func(b *testing.B) {
+ for i := 0; i < b.N; i++ {
+ value.SetZero()
+ }
+ })
+ b.Run(name+"/CachedZero", func(b *testing.B) {
+ for i := 0; i < b.N; i++ {
+ value.Set(zero)
+ }
+ })
+ b.Run(name+"/NewZero", func(b *testing.B) {
+ for i := 0; i < b.N; i++ {
+ value.Set(Zero(value.Type()))
+ }
+ })
+ }
+}
+
+func BenchmarkSelect(b *testing.B) {
+ channel := make(chan int)
+ close(channel)
+ var cases []SelectCase
+ for i := 0; i < 8; i++ {
+ cases = append(cases, SelectCase{
+ Dir: SelectRecv,
+ Chan: ValueOf(channel),
+ })
+ }
+ for _, numCases := range []int{1, 4, 8} {
+ b.Run(strconv.Itoa(numCases), func(b *testing.B) {
+ b.ReportAllocs()
+ for i := 0; i < b.N; i++ {
+ _, _, _ = Select(cases[:numCases])
+ }
+ })
+ }
+}
+
+func BenchmarkCall(b *testing.B) {
+ fv := ValueOf(func(a, b string) {})
+ b.ReportAllocs()
+ b.RunParallel(func(pb *testing.PB) {
+ args := []Value{ValueOf("a"), ValueOf("b")}
+ for pb.Next() {
+ fv.Call(args)
+ }
+ })
+}
+
+type myint int64
+
+func (i *myint) inc() {
+ *i = *i + 1
+}
+
+func BenchmarkCallMethod(b *testing.B) {
+ b.ReportAllocs()
+ z := new(myint)
+
+ v := ValueOf(z.inc)
+ for i := 0; i < b.N; i++ {
+ v.Call(nil)
+ }
+}
+
+func BenchmarkCallArgCopy(b *testing.B) {
+ byteArray := func(n int) Value {
+ return Zero(ArrayOf(n, TypeOf(byte(0))))
+ }
+ sizes := [...]struct {
+ fv Value
+ arg Value
+ }{
+ {ValueOf(func(a [128]byte) {}), byteArray(128)},
+ {ValueOf(func(a [256]byte) {}), byteArray(256)},
+ {ValueOf(func(a [1024]byte) {}), byteArray(1024)},
+ {ValueOf(func(a [4096]byte) {}), byteArray(4096)},
+ {ValueOf(func(a [65536]byte) {}), byteArray(65536)},
+ }
+ for _, size := range sizes {
+ bench := func(b *testing.B) {
+ args := []Value{size.arg}
+ b.SetBytes(int64(size.arg.Len()))
+ b.ResetTimer()
+ b.RunParallel(func(pb *testing.PB) {
+ for pb.Next() {
+ size.fv.Call(args)
+ }
+ })
+ }
+ name := fmt.Sprintf("size=%v", size.arg.Len())
+ b.Run(name, bench)
+ }
+}
+
+func BenchmarkPtrTo(b *testing.B) {
+ // Construct a type with a zero ptrToThis.
+ type T struct{ int }
+ t := SliceOf(TypeOf(T{}))
+ ptrToThis := ValueOf(t).Elem().FieldByName("ptrToThis")
+ if !ptrToThis.IsValid() {
+ b.Fatalf("%v has no ptrToThis field; was it removed from rtype?", t)
+ }
+ if ptrToThis.Int() != 0 {
+ b.Fatalf("%v.ptrToThis unexpectedly nonzero", t)
+ }
+ b.ResetTimer()
+
+ // Now benchmark calling PointerTo on it: we'll have to hit the ptrMap cache on
+ // every call.
+ b.RunParallel(func(pb *testing.PB) {
+ for pb.Next() {
+ PointerTo(t)
+ }
+ })
+}
+
+type B1 struct {
+ X int
+ Y int
+ Z int
+}
+
+func BenchmarkFieldByName1(b *testing.B) {
+ t := TypeOf(B1{})
+ b.RunParallel(func(pb *testing.PB) {
+ for pb.Next() {
+ t.FieldByName("Z")
+ }
+ })
+}
+
+func BenchmarkFieldByName2(b *testing.B) {
+ t := TypeOf(S3{})
+ b.RunParallel(func(pb *testing.PB) {
+ for pb.Next() {
+ t.FieldByName("B")
+ }
+ })
+}
+
+func BenchmarkFieldByName3(b *testing.B) {
+ t := TypeOf(R0{})
+ b.RunParallel(func(pb *testing.PB) {
+ for pb.Next() {
+ t.FieldByName("X")
+ }
+ })
+}
+
+type S struct {
+ i1 int64
+ i2 int64
+}
+
+func BenchmarkInterfaceBig(b *testing.B) {
+ v := ValueOf(S{})
+ b.RunParallel(func(pb *testing.PB) {
+ for pb.Next() {
+ v.Interface()
+ }
+ })
+ b.StopTimer()
+}
+
+func BenchmarkInterfaceSmall(b *testing.B) {
+ v := ValueOf(int64(0))
+ b.RunParallel(func(pb *testing.PB) {
+ for pb.Next() {
+ v.Interface()
+ }
+ })
+}
+
+func BenchmarkNew(b *testing.B) {
+ v := TypeOf(XM{})
+ b.RunParallel(func(pb *testing.PB) {
+ for pb.Next() {
+ New(v)
+ }
+ })
+}
+
+func BenchmarkMap(b *testing.B) {
+ type V *int
+ type S string
+ value := ValueOf((V)(nil))
+ stringKeys := []string{}
+ mapOfStrings := map[string]V{}
+ uint64Keys := []uint64{}
+ mapOfUint64s := map[uint64]V{}
+ userStringKeys := []S{}
+ mapOfUserStrings := map[S]V{}
+ for i := 0; i < 100; i++ {
+ stringKey := fmt.Sprintf("key%d", i)
+ stringKeys = append(stringKeys, stringKey)
+ mapOfStrings[stringKey] = nil
+
+ uint64Key := uint64(i)
+ uint64Keys = append(uint64Keys, uint64Key)
+ mapOfUint64s[uint64Key] = nil
+
+ userStringKey := S(fmt.Sprintf("key%d", i))
+ userStringKeys = append(userStringKeys, userStringKey)
+ mapOfUserStrings[userStringKey] = nil
+ }
+
+ tests := []struct {
+ label string
+ m, keys, value Value
+ }{
+ {"StringKeys", ValueOf(mapOfStrings), ValueOf(stringKeys), value},
+ {"Uint64Keys", ValueOf(mapOfUint64s), ValueOf(uint64Keys), value},
+ {"UserStringKeys", ValueOf(mapOfUserStrings), ValueOf(userStringKeys), value},
+ }
+
+ for _, tt := range tests {
+ b.Run(tt.label, func(b *testing.B) {
+ b.Run("MapIndex", func(b *testing.B) {
+ b.ReportAllocs()
+ for i := 0; i < b.N; i++ {
+ for j := tt.keys.Len() - 1; j >= 0; j-- {
+ tt.m.MapIndex(tt.keys.Index(j))
+ }
+ }
+ })
+ b.Run("SetMapIndex", func(b *testing.B) {
+ b.ReportAllocs()
+ for i := 0; i < b.N; i++ {
+ for j := tt.keys.Len() - 1; j >= 0; j-- {
+ tt.m.SetMapIndex(tt.keys.Index(j), tt.value)
+ }
+ }
+ })
+ })
+ }
+}
+
+func BenchmarkMapIterNext(b *testing.B) {
+ m := ValueOf(map[string]int{"a": 0, "b": 1, "c": 2, "d": 3})
+ it := m.MapRange()
+ for i := 0; i < b.N; i++ {
+ for it.Next() {
+ }
+ it.Reset(m)
+ }
+}