You are dealing in double digit nano differences on an IO call - it makes no difference. Use whichever code is easier to work with and understand.
> On May 30, 2020, at 4:45 AM, amarjeetanandsi...@gmail.com wrote: > > > Hi > > I have a db package, which needs to return a slice of struct(of user,order > etc type). > In the user pkg, I want the slice of user. To achieve this, I have tried 4 > ways, As shown below. > > > Attempt 1: Create a callback func using reflection > > create the user obj & callBack func using reflection & call the callback func > with new doc as parameter. This way looks clean to use in user pkg but using > reflection is costly. (please see the benchmark @ bottom of this mail) > package db > > func QueryResults_CallBack_ReflectionFunc(callBackFuncI interface{}) error { > defer client.Close() > > funcType := reflect.TypeOf(callBackFuncI) > docType := funcType.In(0).Elem() > callBackFunc := reflect.ValueOf(callBackFuncI) > arg := make([]reflect.Value, 1) > > doc := reflect.New(docType) > for client.HasMore() { > if err := client.ReadDocument(doc.Interface()); err != nil { > return err > } > arg[0] = doc > callBackFunc.Call(arg) > } > > return nil > } > > > and at the user pkg side just pass a call back function like... > package user > > func GetUsers_CallBack_ReflectionFunc() []User { > users := make([]User, 0, 5) > db.QueryResults_CallBack_ReflectionFunc(func(user *User) { > users = append(users, *user) > }) > return users > } > > > > > Attempt 2: Pass the callback func & user object > > Pass the callback func & user object from user to db pkg, so that, the db > pkg doesn't have to create one using reflection, thus saving cost of using > reflection > package db > > func QueryResults_CallBack_ObjNFunc(doc interface{}, callBackFunc > func(interface{})) error { > defer client.Close() > > for client.HasMore() { > if err := client.ReadDocument(doc); err != nil { > return err > } > callBackFunc(doc) > } > return nil > } > > > > and in user package it can be used as - > package user > > func GetUsers_CallBack_ObjNFunc() []User { > users := make([]User, 0, 5) > db.QueryResults_CallBack_ObjNFunc(&User{}, func(userI interface{}) { > u := userI.(*User) > users = append(users, *u) > }) > return users > } > > > Attempt 3: Pass the db client in a callback func > package db > > func QueryResults_CallBack_DBClient(callBackFunc func(DbClient) error) error { > defer client.Close() > > for client.HasMore() { > if err := callBackFunc(client); err != nil { > return err > } > } > return nil > } > > > and in user pkg, it can be used as - > package user > > func GetUsers_CallBack_DBClient() []User { > users := make([]User, 0, 5) > db.QueryResults_CallBack_DBClient(func(client db.DbClient) error { > user := User{} > if err := client.ReadDocument(&user); err != nil { > return err > } > users = append(users, user) > return nil > }) > > return users > } > > > > > Attempt 4: Expose the db client > > package db > > func QueryResults_ExposeClient() DbClient { > return client > } > > > and in user package, handle the read document logic like... > package user > > func GetUsers_ExposeClient() []User { > users := make([]User, 0, 5) > > client := db.QueryResults_ExposeClient() > for client.HasMore() { > user := User{} > client.ReadDocument(&user) > users = append(users, user) > } > client.Close() // responsibility of caller to close the client > > return users > } > > > Benchmark > ~/go/src/testReflection master* 5s ❯ go test ./user -cpuprofile cpu.prof > -memprofile mem.prof -bench='BenchmarkGetUser*' -run=^a -benchmem > > BenchmarkGetUsers_CallBackReflectionFunc-12 4426987 263 > ns/op 432 B/op 4 allocs/op > > BenchmarkGetUsers_CallBack_ObjNFunc-12 6293131 186 > ns/op 384 B/op 2 allocs/op > > BenchmarkGetUsers_CallBackClient-12 7858377 147 > ns/op 320 B/op 1 allocs/op > > BenchmarkGetUsers_ExposeClient-12 10273468 106 > ns/op 320 B/op 1 allocs/op > > > > PProf svg > https://raw.githubusercontent.com/amarjeetanandsingh/go_reflection_test/master/pprof_cpu.svg > https://raw.githubusercontent.com/amarjeetanandsingh/go_reflection_test/master/pprof_mem.svg > > > Source Code > You can find the code at > https://github.com/amarjeetanandsingh/go_reflection_test > > > > Based on the performance which approach would you suggest? > Or any optimisation you can suggest for CallBack_ReflectionFunc()? > Or maybe you can purpose a better way? > > > > > -- > You received this message because you are subscribed to the Google Groups > "golang-nuts" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to golang-nuts+unsubscr...@googlegroups.com. > To view this discussion on the web visit > https://groups.google.com/d/msgid/golang-nuts/2570eb2e-1b46-4c3a-8792-8064acd7e5db%40googlegroups.com. -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/CA25C97F-05DB-42BD-B9E1-46B4B8A6A9CC%40ix.netcom.com.