stackitem: use type switch more effectively

Reduce the number of allocations, save some time.

name               old time/op    new time/op    delta
EncodeBinary-8       51.2µs ± 8%    44.6µs ± 7%  -12.79%  (p=0.008 n=5+5)
SerializeSimple-8     523ns ± 5%     449ns ± 4%  -14.27%  (p=0.008 n=5+5)

name               old alloc/op   new alloc/op   delta
EncodeBinary-8        329kB ± 0%     329kB ± 0%   -0.12%  (p=0.008 n=5+5)
SerializeSimple-8      432B ± 0%      408B ± 0%   -5.56%  (p=0.008 n=5+5)

name               old allocs/op  new allocs/op  delta
EncodeBinary-8         36.0 ± 0%      20.0 ± 0%  -44.44%  (p=0.008 n=5+5)
SerializeSimple-8      7.00 ± 0%      6.00 ± 0%  -14.29%  (p=0.008 n=5+5)
This commit is contained in:
Roman Khimov 2021-11-30 22:30:44 +03:00
parent 418ba1dbc3
commit af8a4da6d9

View file

@ -85,6 +85,18 @@ func EncodeBinaryProtected(item Item, w *io.BinWriter) {
w.WriteBytes(sc.data)
}
func (w *serContext) writeArray(item Item, arr []Item, start int) error {
w.seen[item] = sliceNoPointer{}
w.appendVarUint(uint64(len(arr)))
for i := range arr {
if err := w.serialize(arr[i]); err != nil {
return err
}
}
w.seen[item] = sliceNoPointer{start, len(w.data)}
return nil
}
func (w *serContext) serialize(item Item) error {
if v, ok := w.seen[item]; ok {
if v.start == v.end {
@ -127,24 +139,16 @@ func (w *serContext) serialize(item Item) error {
} else {
return fmt.Errorf("%w: Interop", ErrUnserializable)
}
case *Array, *Struct:
w.seen[item] = sliceNoPointer{}
_, isArray := t.(*Array)
if isArray {
w.data = append(w.data, byte(ArrayT))
} else {
w.data = append(w.data, byte(StructT))
case *Array:
w.data = append(w.data, byte(ArrayT))
if err := w.writeArray(item, t.value, start); err != nil {
return err
}
arr := t.Value().([]Item)
w.appendVarUint(uint64(len(arr)))
for i := range arr {
if err := w.serialize(arr[i]); err != nil {
return err
}
case *Struct:
w.data = append(w.data, byte(StructT))
if err := w.writeArray(item, t.value, start); err != nil {
return err
}
w.seen[item] = sliceNoPointer{start, len(w.data)}
case *Map:
w.seen[item] = sliceNoPointer{}