Skip to content

Instantly share code, notes, and snippets.

@mitar
Forked from bruth/invoc_test.go
Last active March 6, 2024 11:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mitar/4ebab2110b591e157440209069d02c79 to your computer and use it in GitHub Desktop.
Save mitar/4ebab2110b591e157440209069d02c79 to your computer and use it in GitHub Desktop.
Method invocation benchmarks
package main
import (
"reflect"
"testing"
)
type myStruct struct {
i int64
}
type Inccer interface {
Inc()
}
func (s *myStruct) Inc() {
s.i = s.i + 1
}
func BenchmarkReflectMethodByNameInterface(b *testing.B) {
i := new(myStruct)
incnReflectMethodByNameInterface(i, b.N)
}
func BenchmarkReflectMethodByName(b *testing.B) {
i := new(myStruct)
incnReflectMethodByName(i, b.N)
}
func BenchmarkReflectMethodCall(b *testing.B) {
i := new(myStruct)
incnReflectCall(i.Inc, b.N)
}
func BenchmarkReflectOnceMethodCall(b *testing.B) {
i := new(myStruct)
incnReflectOnceCall(i.Inc, b.N)
}
func BenchmarkReflectCallInterface(b *testing.B) {
i := new(myStruct)
incnReflectCallInterface(i.Inc, b.N)
}
func BenchmarkStructMethodCall(b *testing.B) {
i := new(myStruct)
incnMethod(i, b.N)
}
func BenchmarkInterfaceMethodCall(b *testing.B) {
i := new(myStruct)
incnInterface(i, b.N)
}
func BenchmarkTypeSwitchMethodCall(b *testing.B) {
i := new(myStruct)
incnSwitch(i, b.N)
}
func BenchmarkTypeAssertionMethodCall(b *testing.B) {
i := new(myStruct)
incnAssertion(i, b.N)
}
func incnReflectMethodByNameInterface(v interface{}, n int) {
s := reflect.ValueOf(v)
f := s.MethodByName("Inc").Interface().(func())
for k := 0; k < n; k++ {
f()
}
}
func incnReflectMethodByName(v interface{}, n int) {
s := reflect.ValueOf(v)
m := s.MethodByName("Inc")
for k := 0; k < n; k++ {
m.Call(nil)
}
}
func incnReflectCall(v interface{}, n int) {
for k := 0; k < n; k++ {
reflect.ValueOf(v).Call(nil)
}
}
func incnReflectOnceCall(v interface{}, n int) {
fn := reflect.ValueOf(v)
for k := 0; k < n; k++ {
fn.Call(nil)
}
}
func incnReflectCallInterface(v interface{}, n int) {
fn := reflect.ValueOf(v).Interface().(func())
for k := 0; k < n; k++ {
fn()
}
}
func incnMethod(s *myStruct, n int) {
for k := 0; k < n; k++ {
s.Inc()
}
}
func incnInterface(s Inccer, n int) {
for k := 0; k < n; k++ {
s.Inc()
}
}
func incnSwitch(s Inccer, n int) {
for k := 0; k < n; k++ {
switch v := s.(type) {
case *myStruct:
v.Inc()
}
}
}
func incnAssertion(s Inccer, n int) {
for k := 0; k < n; k++ {
if ms, ok := s.(*myStruct); ok {
ms.Inc()
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment