Go反射性能瓶颈如何通过零拷贝技术实现优化?

摘要:原文:https:www.yt-blog.top38912 做Go开发的,肯定少不了用反射——解析Tag、拿字段偏移、获取类型信息,ORM、序列化、配置绑定这些地方都要用到。 但是官方的reflect包性能真的不太行,解析一个字段或
原文:https://www.yt-blog.top/38912/ 做Go开发的,肯定少不了用反射——解析Tag、拿字段偏移、获取类型信息,ORM、序列化、配置绑定这些地方都要用到。 但是官方的reflect包性能真的不太行,解析一个字段或Tag要花几十到几百万纳秒,调得多了,直接成性能瓶颈。 很多人只知道「反射慢」,但不知道慢在哪。咱们今天就从runtime层面分析一下,顺便搞个零拷贝的优化方案。 一、先从底层说起 要搞清楚反射的性能问题,得先知道Go底层是怎么回事。 从Go1.14开始,runtime里几个核心类型的内存布局就没变过。这是个关键点。 Go的反射包就是基于runtime层的abi实现的。 reflect/type.go // TypeOf returns the reflection [Type] that represents the dynamic type of i. // If i is a nil interface value, TypeOf returns nil. func TypeOf(i any) Type { return toType(abi.TypeOf(i)) } 其实reflect.Type就是一个接口,上面代码里的toType()把它转成了reflect.rtype。 // rtype is the common implementation of most values. // It is embedded in other struct types. type rtype struct { t abi.Type } func toRType(t *abi.Type) *rtype { return (*rtype)(unsafe.Pointer(t)) } 所以最后拿到的是个abi.Type实例,reflect.rtype只是给它包了一层,提供个友好的接口。也可以换成别的类型专用结构体,但本质上都是对abi.Type的封装。
阅读全文