Created
February 25, 2022 15:57
-
-
Save mariomac/aa29de236211a8e5afedfb34c20c76ce to your computer and use it in GitHub Desktop.
Go reflection API performance
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
All the three benchmarks do the same operation: | |
go test -bench=. ./examples/... -test.run=^$ -benchmem -cpu 2,4,6 | |
? github.com/mariomac/go-pipes/examples/basic [no test files] | |
goos: darwin | |
goarch: amd64 | |
pkg: github.com/mariomac/go-pipes/examples/tests | |
cpu: Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz | |
BenchmarkNative-2 3277838 362.9 ns/op 0 B/op 0 allocs/op | |
BenchmarkNative-4 3263050 364.7 ns/op 0 B/op 0 allocs/op | |
BenchmarkNative-6 3328184 364.1 ns/op 0 B/op 0 allocs/op | |
BenchmarkGenerified-2 1202913 985.0 ns/op 103 B/op 6 allocs/op | |
BenchmarkGenerified-4 1000000 1001 ns/op 103 B/op 6 allocs/op | |
BenchmarkGenerified-6 1225830 1028 ns/op 104 B/op 6 allocs/op | |
BenchmarkGenerifiedMakeFunc-2 1546054 774.1 ns/op 64 B/op 4 allocs/op | |
BenchmarkGenerifiedMakeFunc-4 1470452 824.3 ns/op 64 B/op 4 allocs/op | |
BenchmarkGenerifiedMakeFunc-6 1438862 833.4 ns/op 64 B/op 4 allocs/op |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package tests | |
import ( | |
"reflect" | |
"testing" | |
) | |
func doubler(i int) int { | |
return i * 2 | |
} | |
func generify(function interface{}) (in, out reflect.Value) { | |
fn := reflect.ValueOf(function) | |
inT := reflect.ChanOf(reflect.BothDir, fn.Type().In(0)) | |
in = reflect.MakeChan(inT, 20) | |
outT := reflect.ChanOf(reflect.BothDir, fn.Type().Out(0)) | |
out = reflect.MakeChan(outT, 20) | |
go func() { | |
for v, ok := in.Recv(); ok; v, ok = in.Recv() { | |
ret := fn.Call([]reflect.Value{v}) | |
out.Send(ret[0]) | |
} | |
}() | |
return in, out | |
} | |
func doubleChReflect(fn reflect.Value) func(chans []reflect.Value) []reflect.Value { | |
return func(chans []reflect.Value) []reflect.Value { | |
in, out := chans[0], chans[1] | |
for v, ok := in.Recv(); ok; v, ok = in.Recv() { | |
ret := fn.Call([]reflect.Value{v}) | |
out.Send(ret[0]) | |
} | |
return nil | |
} | |
} | |
func doublerCh(in <-chan int, out chan<- int) { | |
for i := range in { | |
out <- doubler(i) | |
} | |
} | |
func BenchmarkNative(b *testing.B) { | |
in, out := make(chan int, 20), make(chan int, 20) | |
go doublerCh(in, out) | |
for n := 0; n < b.N; n++ { | |
in <- n | |
<-out | |
} | |
} | |
func BenchmarkGenerified(b *testing.B) { | |
in, out := generify(doubler) | |
for n := 0; n < b.N; n++ { | |
in.Send(reflect.ValueOf(n)) | |
v, _ := out.Recv() | |
_ = v.Interface() | |
} | |
} | |
func BenchmarkGenerifiedMakeFunc(b *testing.B) { | |
in, out := make(chan int, 20), make(chan int, 20) | |
var doublerLoop func(in <-chan int, out chan<- int) | |
fn := reflect.ValueOf(&doublerLoop).Elem() | |
actualFun := reflect.MakeFunc(fn.Type(), doubleChReflect(reflect.ValueOf(doubler))) | |
fn.Set(actualFun) | |
go doublerLoop(in, out) | |
for n := 0; n < b.N; n++ { | |
in <- n | |
<-out | |
} | |
} | |
// | |
//func main() { | |
// in, out := generify(doubler) | |
// in.Send(reflect.ValueOf(1)) | |
// in.Send(reflect.ValueOf(2)) | |
// in.Send(reflect.ValueOf(3)) | |
// | |
// v, _ := out.Recv() | |
// fmt.Println(v.Interface()) | |
// v, _ = out.Recv() | |
// fmt.Println(v.Interface()) | |
// v, _ = out.Recv() | |
// fmt.Println(v.Interface()) | |
// | |
// in, out = generify(stringer) | |
// in.Send(reflect.ValueOf(1)) | |
// in.Send(reflect.ValueOf(2)) | |
// in.Send(reflect.ValueOf(3)) | |
// | |
// v, _ = out.Recv() | |
// fmt.Println(v.Interface()) | |
// v, _ = out.Recv() | |
// fmt.Println(v.Interface()) | |
// v, _ = out.Recv() | |
// fmt.Println(v.Interface()) | |
//} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment