1 // Copyright 2022 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
14 var sourceAll = struct {
23 Bool: ValueOf(new(bool)).Elem(),
24 String: ValueOf(new(string)).Elem(),
25 Bytes: ValueOf(new([]byte)).Elem(),
26 NamedBytes: ValueOf(new(namedBytes)).Elem(),
27 BytesArray: ValueOf(new([32]byte)).Elem(),
28 SliceAny: ValueOf(new([]any)).Elem(),
29 MapStringAny: ValueOf(new(map[string]any)).Elem(),
39 func BenchmarkBool(b *testing.B) {
40 for i := 0; i < b.N; i++ {
41 sinkAll.RawBool = sourceAll.Bool.Bool()
45 func BenchmarkString(b *testing.B) {
46 for i := 0; i < b.N; i++ {
47 sinkAll.RawString = sourceAll.String.String()
51 func BenchmarkBytes(b *testing.B) {
52 for i := 0; i < b.N; i++ {
53 sinkAll.RawBytes = sourceAll.Bytes.Bytes()
57 func BenchmarkNamedBytes(b *testing.B) {
58 for i := 0; i < b.N; i++ {
59 sinkAll.RawBytes = sourceAll.NamedBytes.Bytes()
63 func BenchmarkBytesArray(b *testing.B) {
64 for i := 0; i < b.N; i++ {
65 sinkAll.RawBytes = sourceAll.BytesArray.Bytes()
69 func BenchmarkSliceLen(b *testing.B) {
70 for i := 0; i < b.N; i++ {
71 sinkAll.RawInt = sourceAll.SliceAny.Len()
75 func BenchmarkMapLen(b *testing.B) {
76 for i := 0; i < b.N; i++ {
77 sinkAll.RawInt = sourceAll.MapStringAny.Len()
81 func BenchmarkStringLen(b *testing.B) {
82 for i := 0; i < b.N; i++ {
83 sinkAll.RawInt = sourceAll.String.Len()
87 func BenchmarkArrayLen(b *testing.B) {
88 for i := 0; i < b.N; i++ {
89 sinkAll.RawInt = sourceAll.BytesArray.Len()
93 func BenchmarkSliceCap(b *testing.B) {
94 for i := 0; i < b.N; i++ {
95 sinkAll.RawInt = sourceAll.SliceAny.Cap()
99 func BenchmarkDeepEqual(b *testing.B) {
100 for _, bb := range deepEqualPerfTests {
101 b.Run(ValueOf(bb.x).Type().String(), func(b *testing.B) {
103 for i := 0; i < b.N; i++ {
104 sink = DeepEqual(bb.x, bb.y)
110 func BenchmarkMapsDeepEqual(b *testing.B) {
117 for i := 0; i < b.N; i++ {
122 func BenchmarkIsZero(b *testing.B) {
126 type Int1024 struct {
131 ArrayIncomparable [4]_Complex
133 StructIncomparable _Complex
135 ArrayInt_1024 [1024]int
136 ArrayInt_1024_NoZero [1024]int
138 ArrayStruct4Int_1024 [256]Int4
139 ArrayChanInt_1024 [1024]chan int
141 s.ArrayInt_1024_NoZero[512] = 1
144 for i := 0; i < source.NumField(); i++ {
145 name := source.Type().Field(i).Name
146 value := source.Field(i)
147 b.Run(name, func(b *testing.B) {
148 for i := 0; i < b.N; i++ {
149 sink = value.IsZero()
155 func BenchmarkSetZero(b *testing.B) {
156 source := ValueOf(new(struct {
165 Interface interface{ String() string }
173 for i := 0; i < source.NumField(); i++ {
174 name := source.Type().Field(i).Name
175 value := source.Field(i)
176 zero := Zero(value.Type())
177 b.Run(name+"/Direct", func(b *testing.B) {
178 for i := 0; i < b.N; i++ {
182 b.Run(name+"/CachedZero", func(b *testing.B) {
183 for i := 0; i < b.N; i++ {
187 b.Run(name+"/NewZero", func(b *testing.B) {
188 for i := 0; i < b.N; i++ {
189 value.Set(Zero(value.Type()))
195 func BenchmarkSelect(b *testing.B) {
196 channel := make(chan int)
198 var cases []SelectCase
199 for i := 0; i < 8; i++ {
200 cases = append(cases, SelectCase{
202 Chan: ValueOf(channel),
205 for _, numCases := range []int{1, 4, 8} {
206 b.Run(strconv.Itoa(numCases), func(b *testing.B) {
208 for i := 0; i < b.N; i++ {
209 _, _, _ = Select(cases[:numCases])
215 func BenchmarkCall(b *testing.B) {
216 fv := ValueOf(func(a, b string) {})
218 b.RunParallel(func(pb *testing.PB) {
219 args := []Value{ValueOf("a"), ValueOf("b")}
228 func (i *myint) inc() {
232 func BenchmarkCallMethod(b *testing.B) {
237 for i := 0; i < b.N; i++ {
242 func BenchmarkCallArgCopy(b *testing.B) {
243 byteArray := func(n int) Value {
244 return Zero(ArrayOf(n, TypeOf(byte(0))))
246 sizes := [...]struct {
250 {ValueOf(func(a [128]byte) {}), byteArray(128)},
251 {ValueOf(func(a [256]byte) {}), byteArray(256)},
252 {ValueOf(func(a [1024]byte) {}), byteArray(1024)},
253 {ValueOf(func(a [4096]byte) {}), byteArray(4096)},
254 {ValueOf(func(a [65536]byte) {}), byteArray(65536)},
256 for _, size := range sizes {
257 bench := func(b *testing.B) {
258 args := []Value{size.arg}
259 b.SetBytes(int64(size.arg.Len()))
261 b.RunParallel(func(pb *testing.PB) {
267 name := fmt.Sprintf("size=%v", size.arg.Len())
272 func BenchmarkPtrTo(b *testing.B) {
273 // Construct a type with a zero ptrToThis.
275 t := SliceOf(TypeOf(T{}))
276 ptrToThis := ValueOf(t).Elem().FieldByName("PtrToThis")
277 if !ptrToThis.IsValid() {
278 b.Skipf("%v has no ptrToThis field; was it removed from rtype?", t) // TODO fix this at top of refactoring
279 // b.Fatalf("%v has no ptrToThis field; was it removed from rtype?", t)
281 if ptrToThis.Int() != 0 {
282 b.Fatalf("%v.ptrToThis unexpectedly nonzero", t)
286 // Now benchmark calling PointerTo on it: we'll have to hit the ptrMap cache on
288 b.RunParallel(func(pb *testing.PB) {
301 func BenchmarkFieldByName1(b *testing.B) {
303 b.RunParallel(func(pb *testing.PB) {
310 func BenchmarkFieldByName2(b *testing.B) {
312 b.RunParallel(func(pb *testing.PB) {
319 func BenchmarkFieldByName3(b *testing.B) {
321 b.RunParallel(func(pb *testing.PB) {
333 func BenchmarkInterfaceBig(b *testing.B) {
335 b.RunParallel(func(pb *testing.PB) {
343 func BenchmarkInterfaceSmall(b *testing.B) {
344 v := ValueOf(int64(0))
345 b.RunParallel(func(pb *testing.PB) {
352 func BenchmarkNew(b *testing.B) {
354 b.RunParallel(func(pb *testing.PB) {
361 func BenchmarkMap(b *testing.B) {
364 value := ValueOf((V)(nil))
365 stringKeys := []string{}
366 mapOfStrings := map[string]V{}
367 uint64Keys := []uint64{}
368 mapOfUint64s := map[uint64]V{}
369 userStringKeys := []S{}
370 mapOfUserStrings := map[S]V{}
371 for i := 0; i < 100; i++ {
372 stringKey := fmt.Sprintf("key%d", i)
373 stringKeys = append(stringKeys, stringKey)
374 mapOfStrings[stringKey] = nil
376 uint64Key := uint64(i)
377 uint64Keys = append(uint64Keys, uint64Key)
378 mapOfUint64s[uint64Key] = nil
380 userStringKey := S(fmt.Sprintf("key%d", i))
381 userStringKeys = append(userStringKeys, userStringKey)
382 mapOfUserStrings[userStringKey] = nil
389 {"StringKeys", ValueOf(mapOfStrings), ValueOf(stringKeys), value},
390 {"Uint64Keys", ValueOf(mapOfUint64s), ValueOf(uint64Keys), value},
391 {"UserStringKeys", ValueOf(mapOfUserStrings), ValueOf(userStringKeys), value},
394 for _, tt := range tests {
395 b.Run(tt.label, func(b *testing.B) {
396 b.Run("MapIndex", func(b *testing.B) {
398 for i := 0; i < b.N; i++ {
399 for j := tt.keys.Len() - 1; j >= 0; j-- {
400 tt.m.MapIndex(tt.keys.Index(j))
404 b.Run("SetMapIndex", func(b *testing.B) {
406 for i := 0; i < b.N; i++ {
407 for j := tt.keys.Len() - 1; j >= 0; j-- {
408 tt.m.SetMapIndex(tt.keys.Index(j), tt.value)
416 func BenchmarkMapIterNext(b *testing.B) {
417 m := ValueOf(map[string]int{"a": 0, "b": 1, "c": 2, "d": 3})
419 for i := 0; i < b.N; i++ {