1
0
mirror of https://github.com/Mrs4s/MiraiGo.git synced 2025-05-04 19:17:38 +08:00

speed up jce

pkg: github.com/Mrs4s/MiraiGo/binary/jce
BenchmarkJceWriter_WriteJceStructRaw
BenchmarkJceWriter_WriteJceStructRaw-8    	  200443	      5966 ns/op
BenchmarkJceWriter_WriteJceStructRaw2
BenchmarkJceWriter_WriteJceStructRaw2-8   	  481285	      2659 ns/op
This commit is contained in:
wdvxdr 2021-01-30 18:26:48 +08:00
parent e9537a09a2
commit 59e689bd46

View File

@ -3,8 +3,10 @@ package jce
import (
"bytes"
goBinary "encoding/binary"
"github.com/modern-go/reflect2"
"reflect"
"strconv"
"sync"
)
type JceWriter struct {
@ -200,24 +202,44 @@ func (w *JceWriter) WriteObject(i interface{}, tag int) {
}
}
type decoder []struct {
fieldID int
id int
}
var decoderCache = sync.Map{}
// WriteJceStructRaw 写入 Jce 结构体
func (w *JceWriter) WriteJceStructRaw(s IJceStruct) {
var (
t = reflect.TypeOf(s).Elem()
v = reflect.ValueOf(s).Elem()
v = reflect.ValueOf(s).Elem()
ty2 = reflect2.TypeOf(s)
jceDec decoder
)
for i := 0; i < t.NumField(); i++ {
strId := t.Field(i).Tag.Get("jceId")
if strId == "" {
continue
}
id, err := strconv.Atoi(strId)
if err != nil {
continue
}
obj := v.Field(i).Interface()
if obj != nil {
w.WriteObject(v.Field(i).Interface(), id)
dec, ok := decoderCache.Load(ty2)
if ok { // 从缓存中加载
jceDec = dec.(decoder)
} else { // 初次反射
jceDec = decoder{}
t := reflect.TypeOf(s).Elem()
for i := 0; i < t.NumField(); i++ {
strId := t.Field(i).Tag.Get("jceId")
if strId == "" {
continue
}
id, err := strconv.Atoi(strId)
if err != nil {
continue
}
jceDec = append(jceDec, struct {
fieldID int
id int
}{fieldID: i, id: id})
}
decoderCache.Store(ty2, jceDec) // 存入缓存
}
for _, dec := range jceDec {
w.WriteObject(v.Field(dec.fieldID).Interface(), dec.id)
}
}