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

refactor(jce): use ReadMap & remove ReadMapF.

name                            old time/op    new time/op    delta
RequestDataVersion2_ReadFrom-8    5.58µs ± 1%    5.78µs ± 2%   +3.64%  (p=0.000 n=9+9)

name                            old speed      new speed      delta
RequestDataVersion2_ReadFrom-8  16.7MB/s ± 1%  16.1MB/s ± 2%   -3.52%  (p=0.000 n=9+9)

name                            old alloc/op   new alloc/op   delta
RequestDataVersion2_ReadFrom-8    5.40kB ± 0%    3.74kB ± 0%  -30.67%  (p=0.000 n=10+10)

name                            old allocs/op  new allocs/op  delta
RequestDataVersion2_ReadFrom-8       147 ± 0%       136 ± 0%   -7.48%  (p=0.000 n=10+10)
This commit is contained in:
wdvxdr 2021-08-12 23:24:58 +08:00
parent aa72b4b730
commit 9814f5295d
No known key found for this signature in database
GPG Key ID: 703F8C071DE7A1B6
3 changed files with 79 additions and 9 deletions

View File

@ -2,6 +2,7 @@ package jce
import ( import (
"bytes" "bytes"
goBinary "encoding/binary"
"math" "math"
"reflect" "reflect"
) )
@ -113,12 +114,12 @@ func (r *JceReader) readUInt16() uint16 {
func (r *JceReader) readInt32() int32 { func (r *JceReader) readInt32() int32 {
b := r.readBytes(4) b := r.readBytes(4)
return (int32(b[0]) << 24) | (int32(b[1]) << 16) | (int32(b[2]) << 8) | int32(b[3]) return int32(goBinary.BigEndian.Uint32(b))
} }
func (r *JceReader) readInt64() int64 { func (r *JceReader) readInt64() int64 {
b := r.readBytes(8) b := r.readBytes(8)
return (int64(b[0]) << 56) | (int64(b[1]) << 48) | (int64(b[2]) << 40) | (int64(b[3]) << 32) | (int64(b[4]) << 24) | (int64(b[5]) << 16) | (int64(b[6]) << 8) | int64(b[7]) return int64(goBinary.BigEndian.Uint64(b))
} }
func (r *JceReader) readFloat32() float32 { func (r *JceReader) readFloat32() float32 {
@ -334,7 +335,32 @@ func (r *JceReader) ReadJceStruct(obj IJceStruct, tag int) {
r.skipToStructEnd() r.skipToStructEnd()
} }
func (r *JceReader) ReadMapF(tag int, f func(interface{}, interface{})) { func (r *JceReader) ReadMap(i interface{}, tag int) {
v := reflect.ValueOf(i)
if v.Kind() != reflect.Map {
return
}
if !r.skipToTag(tag) {
return
}
t := v.Type()
kt := t.Key()
kv := reflect.New(kt)
vt := t.Elem()
vv := reflect.New(vt)
r.readHead()
s := r.ReadInt32(0)
for i := 0; i < int(s); i++ {
r.ReadObject(kv.Interface(), 0)
r.ReadObject(vv.Interface(), 1)
v.SetMapIndex(kv.Elem(), vv.Elem())
}
}
func (r *JceReader) _ReadMapF(tag int, f func(interface{}, interface{})) {
if !r.skipToTag(tag) { if !r.skipToTag(tag) {
return return
} }
@ -408,6 +434,11 @@ func (r *JceReader) ReadObject(i interface{}, tag int) {
if va.Kind() != reflect.Ptr || va.IsNil() { if va.Kind() != reflect.Ptr || va.IsNil() {
return return
} }
if ve := va.Elem(); ve.Kind() == reflect.Map {
ve.Set(reflect.MakeMap(ve.Type()))
r.ReadMap(ve.Interface(), tag)
return
}
switch o := i.(type) { switch o := i.(type) {
case *byte: case *byte:
*o = r.ReadByte(tag) *o = r.ReadByte(tag)

View File

@ -41,3 +41,43 @@ func BenchmarkJceReader_ReadSlice(b *testing.B) {
r.ReadSlice(&result, 1) r.ReadSlice(&result, 1)
} }
} }
var req = RequestDataVersion2{
Map: map[string]map[string][]byte{
"1": {
"123": []byte(`123`),
},
"2": {
"123": []byte(`123`),
},
"3": {
"123": []byte(`123`),
},
"4": {
"123": []byte(`123`),
},
"5": {
"123": []byte(`123`),
},
}}
func TestRequestDataVersion2_ReadFrom(t *testing.T) {
// todo(wdv): fuzz test
w := NewJceWriter()
w.WriteObject(req.Map, 0)
src := w.Bytes()
result := RequestDataVersion2{}
result.ReadFrom(NewJceReader(src))
assert.Equal(t, req, result)
}
func BenchmarkRequestDataVersion2_ReadFrom(b *testing.B) {
w := NewJceWriter()
w.WriteObject(req.Map, 0)
src := w.Bytes()
b.SetBytes(int64(len(src)))
result := &RequestDataVersion2{}
for i := 0; i < b.N; i++ {
result.ReadFrom(NewJceReader(src))
}
}

View File

@ -557,8 +557,8 @@ func (pkt *RequestPacket) ReadFrom(r *JceReader) {
pkt.SFuncName = r.ReadString(6) pkt.SFuncName = r.ReadString(6)
r.ReadSlice(&pkt.SBuffer, 7) r.ReadSlice(&pkt.SBuffer, 7)
pkt.ITimeout = r.ReadInt32(8) pkt.ITimeout = r.ReadInt32(8)
r.ReadMapF(9, func(k interface{}, v interface{}) { pkt.Context[k.(string)] = v.(string) }) r.ReadMap(pkt.Context, 9)
r.ReadMapF(10, func(k interface{}, v interface{}) { pkt.Status[k.(string)] = v.(string) }) r.ReadMap(pkt.Status, 10)
} }
func (pkt *RequestDataVersion3) ToBytes() []byte { func (pkt *RequestDataVersion3) ToBytes() []byte {
@ -569,9 +569,7 @@ func (pkt *RequestDataVersion3) ToBytes() []byte {
func (pkt *RequestDataVersion3) ReadFrom(r *JceReader) { func (pkt *RequestDataVersion3) ReadFrom(r *JceReader) {
pkt.Map = make(map[string][]byte) pkt.Map = make(map[string][]byte)
r.ReadMapF(0, func(k interface{}, v interface{}) { r.ReadMap(pkt.Map, 0)
pkt.Map[k.(string)] = v.([]byte)
})
} }
func (pkt *RequestDataVersion2) ToBytes() []byte { func (pkt *RequestDataVersion2) ToBytes() []byte {
@ -582,7 +580,8 @@ func (pkt *RequestDataVersion2) ToBytes() []byte {
func (pkt *RequestDataVersion2) ReadFrom(r *JceReader) { func (pkt *RequestDataVersion2) ReadFrom(r *JceReader) {
pkt.Map = make(map[string]map[string][]byte) pkt.Map = make(map[string]map[string][]byte)
r.ReadMapF(0, func(k interface{}, v interface{}) { // r.ReadMap(pkt.Map, 0)
r._ReadMapF(0, func(k interface{}, v interface{}) {
pkt.Map[k.(string)] = make(map[string][]byte) pkt.Map[k.(string)] = make(map[string][]byte)
for k2, v := range v.(map[interface{}]interface{}) { for k2, v := range v.(map[interface{}]interface{}) {
pkt.Map[k.(string)][k2.(string)] = v.([]byte) pkt.Map[k.(string)][k2.(string)] = v.([]byte)