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 }