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) {
123 source := ValueOf(struct {
125 ArrayIncomparable [4]_Complex
127 StructIncomparable _Complex
130 for i := 0; i < source.NumField(); i++ {
131 name := source.Type().Field(i).Name
132 value := source.Field(i)
133 b.Run(name, func(b *testing.B) {
134 for i := 0; i < b.N; i++ {
135 sink = value.IsZero()
141 func BenchmarkSetZero(b *testing.B) {
142 source := ValueOf(new(struct {
151 Interface interface{ String() string }
159 for i := 0; i < source.NumField(); i++ {
160 name := source.Type().Field(i).Name
161 value := source.Field(i)
162 zero := Zero(value.Type())
163 b.Run(name+"/Direct", func(b *testing.B) {
164 for i := 0; i < b.N; i++ {
168 b.Run(name+"/CachedZero", func(b *testing.B) {
169 for i := 0; i < b.N; i++ {
173 b.Run(name+"/NewZero", func(b *testing.B) {
174 for i := 0; i < b.N; i++ {
175 value.Set(Zero(value.Type()))
181 func BenchmarkSelect(b *testing.B) {
182 channel := make(chan int)
184 var cases []SelectCase
185 for i := 0; i < 8; i++ {
186 cases = append(cases, SelectCase{
188 Chan: ValueOf(channel),
191 for _, numCases := range []int{1, 4, 8} {
192 b.Run(strconv.Itoa(numCases), func(b *testing.B) {
194 for i := 0; i < b.N; i++ {
195 _, _, _ = Select(cases[:numCases])
201 func BenchmarkCall(b *testing.B) {
202 fv := ValueOf(func(a, b string) {})
204 b.RunParallel(func(pb *testing.PB) {
205 args := []Value{ValueOf("a"), ValueOf("b")}
214 func (i *myint) inc() {
218 func BenchmarkCallMethod(b *testing.B) {
223 for i := 0; i < b.N; i++ {
228 func BenchmarkCallArgCopy(b *testing.B) {
229 byteArray := func(n int) Value {
230 return Zero(ArrayOf(n, TypeOf(byte(0))))
232 sizes := [...]struct {
236 {ValueOf(func(a [128]byte) {}), byteArray(128)},
237 {ValueOf(func(a [256]byte) {}), byteArray(256)},
238 {ValueOf(func(a [1024]byte) {}), byteArray(1024)},
239 {ValueOf(func(a [4096]byte) {}), byteArray(4096)},
240 {ValueOf(func(a [65536]byte) {}), byteArray(65536)},
242 for _, size := range sizes {
243 bench := func(b *testing.B) {
244 args := []Value{size.arg}
245 b.SetBytes(int64(size.arg.Len()))
247 b.RunParallel(func(pb *testing.PB) {
253 name := fmt.Sprintf("size=%v", size.arg.Len())
258 func BenchmarkPtrTo(b *testing.B) {
259 // Construct a type with a zero ptrToThis.
261 t := SliceOf(TypeOf(T{}))
262 ptrToThis := ValueOf(t).Elem().FieldByName("PtrToThis")
263 if !ptrToThis.IsValid() {
264 b.Skipf("%v has no ptrToThis field; was it removed from rtype?", t) // TODO fix this at top of refactoring
265 // b.Fatalf("%v has no ptrToThis field; was it removed from rtype?", t)
267 if ptrToThis.Int() != 0 {
268 b.Fatalf("%v.ptrToThis unexpectedly nonzero", t)
272 // Now benchmark calling PointerTo on it: we'll have to hit the ptrMap cache on
274 b.RunParallel(func(pb *testing.PB) {
287 func BenchmarkFieldByName1(b *testing.B) {
289 b.RunParallel(func(pb *testing.PB) {
296 func BenchmarkFieldByName2(b *testing.B) {
298 b.RunParallel(func(pb *testing.PB) {
305 func BenchmarkFieldByName3(b *testing.B) {
307 b.RunParallel(func(pb *testing.PB) {
319 func BenchmarkInterfaceBig(b *testing.B) {
321 b.RunParallel(func(pb *testing.PB) {
329 func BenchmarkInterfaceSmall(b *testing.B) {
330 v := ValueOf(int64(0))
331 b.RunParallel(func(pb *testing.PB) {
338 func BenchmarkNew(b *testing.B) {
340 b.RunParallel(func(pb *testing.PB) {
347 func BenchmarkMap(b *testing.B) {
350 value := ValueOf((V)(nil))
351 stringKeys := []string{}
352 mapOfStrings := map[string]V{}
353 uint64Keys := []uint64{}
354 mapOfUint64s := map[uint64]V{}
355 userStringKeys := []S{}
356 mapOfUserStrings := map[S]V{}
357 for i := 0; i < 100; i++ {
358 stringKey := fmt.Sprintf("key%d", i)
359 stringKeys = append(stringKeys, stringKey)
360 mapOfStrings[stringKey] = nil
362 uint64Key := uint64(i)
363 uint64Keys = append(uint64Keys, uint64Key)
364 mapOfUint64s[uint64Key] = nil
366 userStringKey := S(fmt.Sprintf("key%d", i))
367 userStringKeys = append(userStringKeys, userStringKey)
368 mapOfUserStrings[userStringKey] = nil
375 {"StringKeys", ValueOf(mapOfStrings), ValueOf(stringKeys), value},
376 {"Uint64Keys", ValueOf(mapOfUint64s), ValueOf(uint64Keys), value},
377 {"UserStringKeys", ValueOf(mapOfUserStrings), ValueOf(userStringKeys), value},
380 for _, tt := range tests {
381 b.Run(tt.label, func(b *testing.B) {
382 b.Run("MapIndex", func(b *testing.B) {
384 for i := 0; i < b.N; i++ {
385 for j := tt.keys.Len() - 1; j >= 0; j-- {
386 tt.m.MapIndex(tt.keys.Index(j))
390 b.Run("SetMapIndex", func(b *testing.B) {
392 for i := 0; i < b.N; i++ {
393 for j := tt.keys.Len() - 1; j >= 0; j-- {
394 tt.m.SetMapIndex(tt.keys.Index(j), tt.value)
402 func BenchmarkMapIterNext(b *testing.B) {
403 m := ValueOf(map[string]int{"a": 0, "b": 1, "c": 2, "d": 3})
405 for i := 0; i < b.N; i++ {