mirror of
https://github.com/golang/go
synced 2024-10-14 03:43:28 +00:00
reflect: move benchmarks to its own file
all_test.go is quite big, so let it contain tests only. Change-Id: I5003db4a8b1e2384ea8470f5e89e1c26d61d10ae Reviewed-on: https://go-review.googlesource.com/c/go/+/429759 TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Ian Lance Taylor <iant@google.com> Auto-Submit: Cuong Manh Le <cuong.manhle.vn@gmail.com> Reviewed-by: Jenny Rakoczy <jenny@golang.org> Run-TryBot: Cuong Manh Le <cuong.manhle.vn@gmail.com>
This commit is contained in:
parent
6f7c9ea855
commit
5bbee7a095
|
@ -1201,17 +1201,6 @@ func TestDeepEqualAllocs(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
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)
|
||||
|
@ -1448,65 +1437,6 @@ func TestIsZero(t *testing.T) {
|
|||
}()
|
||||
}
|
||||
|
||||
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
|
||||
|
@ -2020,26 +1950,6 @@ func TestSelectNop(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
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.
|
||||
|
@ -2218,63 +2128,6 @@ func TestCallReturnsEmpty(t *testing.T) {
|
|||
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 })
|
||||
|
@ -3438,28 +3291,6 @@ func TestPtrToGC(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
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
|
||||
|
@ -6318,30 +6149,6 @@ func TestFuncOf(t *testing.T) {
|
|||
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
|
||||
|
@ -6420,30 +6227,6 @@ func TestEmbed(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
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")
|
||||
|
@ -6454,15 +6237,6 @@ func TestAllocsInterfaceBig(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
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")
|
||||
|
@ -7481,70 +7255,6 @@ func TestOffsetLock(t *testing.T) {
|
|||
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
|
||||
|
@ -7858,16 +7568,6 @@ func TestMapIterNext(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
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}
|
||||
|
@ -8053,91 +7753,6 @@ type (
|
|||
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)
|
||||
|
|
397
src/reflect/benchmark_test.go
Normal file
397
src/reflect/benchmark_test.go
Normal file
|
@ -0,0 +1,397 @@
|
|||
// 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)
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue