1
0
mirror of https://github.com/Mrs4s/MiraiGo.git synced 2025-05-04 11:07:40 +08:00
MiraiGo/binary/protobuf.go
wdvxdr 21ff14fd5c
optimize(binary): allow inline (*encoder).svarint
name                       old time/op  new time/op  delta
encoder_svarint/short-8   7.12ns ± 2%  6.24ns ± 2%  -12.36%  (p=0.000 n=10+9)
encoder_svarint/medium-8  8.86ns ± 3%  7.82ns ± 2%  -11.76%  (p=0.000 n=10+10)
encoder_svarint/large-8   12.2ns ± 1%  11.4ns ± 2%   -5.99%  (p=0.000 n=10+10)

BTW, (*encoder).u32 and (*encoder).u64 can be inlined with go1.18
2021-11-07 13:56:40 +08:00

89 lines
1.6 KiB
Go

package binary
import (
"bytes"
"encoding/binary"
"math"
)
type DynamicProtoMessage map[uint64]interface{}
type encoder struct {
bytes.Buffer
}
func (msg DynamicProtoMessage) Encode() []byte {
en := &encoder{}
for id, value := range msg {
key := id << 3
switch v := value.(type) {
case bool:
en.uvarint(key | 0)
vi := uint64(0)
if v {
vi = 1
}
en.uvarint(vi)
case int:
en.uvarint(key | 0)
en.svarint(int64(v))
case int32:
en.uvarint(key | 0)
en.svarint(int64(v))
case int64:
en.uvarint(key | 0)
en.svarint(v)
case uint32:
en.uvarint(key | 0)
en.uvarint(uint64(v))
case uint64:
en.uvarint(key | 0)
en.uvarint(v)
case float32:
en.uvarint(key | 5)
en.u32(math.Float32bits(v))
case float64:
en.uvarint(key | 1)
en.u64(math.Float64bits(v))
case string:
en.uvarint(key | 2)
b := []byte(v)
en.uvarint(uint64(len(b)))
_, _ = en.Write(b)
case []uint64:
for i := 0; i < len(v); i++ {
en.uvarint(key | 0)
en.uvarint(v[i])
}
case DynamicProtoMessage:
en.uvarint(key | 2)
b := v.Encode()
en.uvarint(uint64(len(b)))
_, _ = en.Write(b)
}
}
return en.Bytes()
}
func (en *encoder) uvarint(v uint64) {
var b [binary.MaxVarintLen64]byte
n := binary.PutUvarint(b[:], v)
_, _ = en.Write(b[:n])
}
func (en *encoder) svarint(v int64) {
en.uvarint(uint64(v)<<1 ^ uint64(v>>63))
}
func (en *encoder) u32(v uint32) {
var b [8]byte
binary.LittleEndian.PutUint32(b[:], v)
_, _ = en.Write(b[:])
}
func (en *encoder) u64(v uint64) {
var b [8]byte
binary.LittleEndian.PutUint64(b[:], v)
_, _ = en.Write(b[:])
}