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
```
';