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

speed up jce writer again

BenchmarkJceWriter_WriteJceStructRaw
BenchmarkJceWriter_WriteJceStructRaw-8    	  414883	      2659 ns/op
BenchmarkJceWriter_WriteJceStructRaw2
BenchmarkJceWriter_WriteJceStructRaw2-8   	  925503	      1460 ns/op
又快了1倍
This commit is contained in:
wdvxdr 2021-02-02 13:21:28 +08:00
parent a782ccbf10
commit 449fd49fd3
No known key found for this signature in database
GPG Key ID: 55FF1414A69CEBA6

View File

@ -7,6 +7,7 @@ import (
"reflect" "reflect"
"strconv" "strconv"
"sync" "sync"
"unsafe"
) )
type JceWriter struct { type JceWriter struct {
@ -203,8 +204,9 @@ func (w *JceWriter) WriteObject(i interface{}, tag int) {
} }
type decoder []struct { type decoder []struct {
fieldID int ty reflect2.Type
id int offset uintptr
id int
} }
var decoderCache = sync.Map{} var decoderCache = sync.Map{}
@ -212,7 +214,6 @@ var decoderCache = sync.Map{}
// WriteJceStructRaw 写入 Jce 结构体 // WriteJceStructRaw 写入 Jce 结构体
func (w *JceWriter) WriteJceStructRaw(s IJceStruct) { func (w *JceWriter) WriteJceStructRaw(s IJceStruct) {
var ( var (
v = reflect.ValueOf(s).Elem()
ty2 = reflect2.TypeOf(s) ty2 = reflect2.TypeOf(s)
jceDec decoder jceDec decoder
) )
@ -221,9 +222,10 @@ func (w *JceWriter) WriteJceStructRaw(s IJceStruct) {
jceDec = dec.(decoder) jceDec = dec.(decoder)
} else { // 初次反射 } else { // 初次反射
jceDec = decoder{} jceDec = decoder{}
t := reflect.TypeOf(s).Elem() t := reflect2.TypeOf(s).(reflect2.PtrType).Elem().(reflect2.StructType)
for i := 0; i < t.NumField(); i++ { for i := 0; i < t.NumField(); i++ {
strId := t.Field(i).Tag.Get("jceId") field := t.Field(i)
strId := field.Tag().Get("jceId")
if strId == "" { if strId == "" {
continue continue
} }
@ -232,14 +234,15 @@ func (w *JceWriter) WriteJceStructRaw(s IJceStruct) {
continue continue
} }
jceDec = append(jceDec, struct { jceDec = append(jceDec, struct {
fieldID int ty reflect2.Type
id int offset uintptr
}{fieldID: i, id: id}) id int
}{ty: field.Type(), offset: field.Offset(), id: id})
} }
decoderCache.Store(ty2, jceDec) // 存入缓存 decoderCache.Store(ty2, jceDec) // 存入缓存
} }
for _, dec := range jceDec { for _, dec := range jceDec {
obj := v.Field(dec.fieldID).Interface() var obj = dec.ty.UnsafeIndirect(unsafe.Pointer(uintptr(reflect2.PtrOf(s)) + dec.offset)) // MAGIC!
if obj != nil { if obj != nil {
w.WriteObject(obj, dec.id) w.WriteObject(obj, dec.id)
} }