Skip to content

Instantly share code, notes, and snippets.

@dugancathal
Created May 5, 2015 06:42
Show Gist options
  • Save dugancathal/26a7949ea50058201f4c to your computer and use it in GitHub Desktop.
Save dugancathal/26a7949ea50058201f4c to your computer and use it in GitHub Desktop.
Set ID on a struct if it exists and hasn't already been set.
package reflectiontest
import "reflect"
type ThingWithId struct {
Id string
Name string
}
type ThingWithoutId struct {
Name string
}
func CopyOfWithId(id string, t interface{}) interface{} {
val := reflect.ValueOf(t)
if _, hasIdField := val.Type().FieldByName("Id"); !hasIdField {
return t
}
if val.FieldByName("Id").Interface() != "" {
return t
}
newbie := reflect.New(val.Type()).Elem()
for i := 0; i < val.NumField(); i++ {
newbie.Field(i).Set(val.Field(i))
}
newbie.FieldByName("Id").SetString(id)
return newbie.Interface()
}
package reflectiontest_test
import (
"testing"
"github.com/dugancathal/reflection-test"
)
func BenchmarkWithIdAndNewThingReflect(b *testing.B) {
for n := 0; n < b.N; n++ {
reflectiontest.CopyOfWithId("imma id", reflectiontest.ThingWithId{
Name: "Other item",
})
}
}
func BenchmarkWithIdAndWithoutNewThingReflect(b *testing.B) {
for n := 0; n < b.N; n++ {
reflectiontest.CopyOfWithId("imma id", reflectiontest.ThingWithId{
Id: "already set",
Name: "Other item",
})
}
}
func BenchmarkWithoutIdOrNewThingReflect(b *testing.B) {
for n := 0; n < b.N; n++ {
reflectiontest.CopyOfWithId("imma id", reflectiontest.ThingWithoutId{
Name: "Other item",
})
}
}
@dugancathal
Copy link
Author

Some benchmarks on reflection in Golang. On my machine:

$ go test -bench=.
testing: warning: no tests to run
PASS
BenchmarkWithIdAndNewThingReflect        2000000               992 ns/op
BenchmarkWithIdAndWithoutNewThingReflect         3000000               430 ns/op
BenchmarkWithoutIdOrNewThingReflect     20000000               115 ns/op
ok      github.com/dugancathal/reflection-test  7.141s

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment