Reflect 提高反射性能

最后更新于:2022-04-02 02:36:19

[TOC] ## 反射的性能 ### 创建对象 ``` func BenchmarkNew(b *testing.B) { var config *Config for i := 0; i < b.N; i++ { config = new(Config) } _ = config } func BenchmarkReflectNew(b *testing.B) { var config *Config typ := reflect.TypeOf(Config{}) b.ResetTimer() for i := 0; i < b.N; i++ { config, _ = reflect.New(typ).Interface().(*Config) } _ = config } ``` 性能 ``` BenchmarkNew-8 26478909 40.9 ns/op BenchmarkReflectNew-8 18983700 62.1 ns/op ``` ### 修改字段的值 通过反射获取结构体的字段有两种方式,一种是`FieldByName`,另一种是`Field` ``` func BenchmarkSet(b *testing.B) { config := new(Config) b.ResetTimer() for i := 0; i < b.N; i++ { config.Name = "name" config.IP = "ip" config.URL = "url" config.Timeout = "timeout" } } func BenchmarkReflect_FieldSet(b *testing.B) { typ := reflect.TypeOf(Config{}) ins := reflect.New(typ).Elem() b.ResetTimer() for i := 0; i < b.N; i++ { ins.Field(0).SetString("name") ins.Field(1).SetString("ip") ins.Field(2).SetString("url") ins.Field(3).SetString("timeout") } } func BenchmarkReflect_FieldByNameSet(b *testing.B) { typ := reflect.TypeOf(Config{}) ins := reflect.New(typ).Elem() b.ResetTimer() for i := 0; i < b.N; i++ { ins.FieldByName("Name").SetString("name") ins.FieldByName("IP").SetString("ip") ins.FieldByName("URL").SetString("url") ins.FieldByName("Timeout").SetString("timeout") } } func BenchmarkReflect_FieldByNameCacheSet(b *testing.B) { typ := reflect.TypeOf(Config{}) cache := make(map[string]int) for i := 0; i < typ.NumField(); i++ { cache[typ.Field(i).Name] = i } ins := reflect.New(typ).Elem() b.ResetTimer() for i := 0; i < b.N; i++ { ins.Field(cache["Name"]).SetString("name") ins.Field(cache["IP"]).SetString("ip") ins.Field(cache["URL"]).SetString("url") ins.Field(cache["Timeout"]).SetString("timeout") } } ``` 压测结果 ``` BenchmarkSet-8 1000000000 0.302 ns/op BenchmarkReflect_FieldSet-8 33913672 34.5 ns/op BenchmarkReflect_FieldByNameSet-8 3775234 316 ns/op BenchmarkReflect_FieldByNameCacheSet-8 14575906 78.2 ns/op ```
';