Skip to content

Instantly share code, notes, and snippets.

@SKumarSpace
Last active March 29, 2023 01:24
Show Gist options
  • Save SKumarSpace/931bee5033eff280b20e4766e828a4bc to your computer and use it in GitHub Desktop.
Save SKumarSpace/931bee5033eff280b20e4766e828a4bc to your computer and use it in GitHub Desktop.
package main
import (
"encoding/json"
"fmt"
"reflect"
"testing"
)
type Person struct {
Name string
Age string
}
func MapToStruct[T any](m map[string]string, s *T) error {
structValue := reflect.ValueOf(s).Elem()
for k, v := range m {
structFieldValue := structValue.FieldByName(k)
if !structFieldValue.IsValid() {
return fmt.Errorf("no such field: %s in obj", k)
}
if !structFieldValue.CanSet() {
return fmt.Errorf("cannot set %s field value", k)
}
fieldValueT := reflect.ValueOf(v)
if structFieldValue.Type() != fieldValueT.Type() {
return fmt.Errorf("provided value type didn't match obj field type")
}
structFieldValue.Set(fieldValueT)
}
return nil
}
func BenchmarkJSONMapToStruct(b *testing.B) {
m := map[string]string{
"Name": "Alice",
"Age": "30",
}
for i := 0; i < b.N; i++ {
var p Person
jsonData, err := json.Marshal(m)
if err != nil {
b.Error(err)
}
err = json.Unmarshal(jsonData, &p)
if err != nil {
b.Error(err)
}
}
}
func BenchmarkReflectMapToStruct(b *testing.B) {
m := map[string]string{
"Name": "Alice",
"Age": "30",
}
for i := 0; i < b.N; i++ {
var p Person
err := MapToStruct(m, &p)
if err != nil {
b.Error(err)
}
}
}

Benchmark Results

goos: windows
goarch: amd64
pkg: go-struct-benchmarks
cpu: AMD Ryzen Threadripper 3960X 24-Core Processor 
Benchmark Iterations Time/Iteration Memory/Iteration Allocs/Iteration
BenchmarkJSONMapToStruct-48 655564 1702 ns/op 617 B/op 16 allocs/op
BenchmarkReflectMapToStruct-48 3228502 376.7 ns/op 80 B/op 5 allocs/op
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment