github.com/nyan233/littlerpc@v0.4.6-0.20230316182519-0c8d5c48abaf/internal/reflect/call_test.go (about)

     1  package reflect
     2  
     3  import (
     4  	"reflect"
     5  	"testing"
     6  	"unsafe"
     7  )
     8  
     9  type BenchType struct{}
    10  
    11  func (b *BenchType) CallMock(a0 int, a1 string, a2 int64, a3 int64, a4 uintptr) (string, string, string) {
    12  	return "", "", ""
    13  }
    14  
    15  type UnsafeFunc func(ptr unsafe.Pointer, a0 int, a1 string, a2 int64, a3 int64, a4 uintptr) (string, string, string)
    16  
    17  type Method struct {
    18  	typ  unsafe.Pointer
    19  	data UnsafeFunc
    20  }
    21  
    22  // flag = "gcflags "-l"
    23  func BenchmarkCall(b *testing.B) {
    24  	b.ReportAllocs()
    25  	bt := reflect.ValueOf(new(BenchType))
    26  	b.Run("ReflectCall", func(b *testing.B) {
    27  		args := []reflect.Value{
    28  			reflect.ValueOf(int(0)),
    29  			reflect.ValueOf("hello"),
    30  			reflect.ValueOf(int64(100)),
    31  			reflect.ValueOf(int64(100)),
    32  			reflect.ValueOf(uintptr(10000)),
    33  		}
    34  		method := bt.Method(0)
    35  		for i := 0; i < b.N; i++ {
    36  			method.Call(args)
    37  		}
    38  	})
    39  	b.Run("MethodValueCall", func(b *testing.B) {
    40  		method := bt.Method(0).Interface().(func(a0 int, a1 string, a2 int64, a3 int64, a4 uintptr) (string, string, string))
    41  		for i := 0; i < b.N; i++ {
    42  			method(0, "hello", 100, 100, 10000)
    43  		}
    44  	})
    45  	b.Run("AnonymousFunctionCall", func(b *testing.B) {
    46  		bt := new(BenchType).CallMock
    47  		for i := 0; i < b.N; i++ {
    48  			bt(0, "hello", 100, 100, 10000)
    49  		}
    50  	})
    51  	b.Run("UnsafeCall", func(b *testing.B) {
    52  		val := bt.Type().Method(0)
    53  		var uf UnsafeFunc
    54  		method := (*Method)(unsafe.Pointer(&val.Func))
    55  		uf = method.data
    56  		ptr := bt.UnsafePointer()
    57  		for i := 0; i < b.N; i++ {
    58  			uf(ptr, 0, "hello", 100, 100, 10000)
    59  		}
    60  	})
    61  	b.Run("FunctionCall", func(b *testing.B) {
    62  		bt := new(BenchType)
    63  		for i := 0; i < b.N; i++ {
    64  			_, _, _ = bt.CallMock(0, "hello", 100, 100, 1000)
    65  		}
    66  	})
    67  }