stackitem: add some hint to 'seen' maps

It's empirical, we usually have one container, but four is likely to fit most
of regular cases.
This commit is contained in:
Roman Khimov 2021-11-30 19:51:52 +03:00
parent 9576e10d04
commit 3eed9d06f8
3 changed files with 11 additions and 5 deletions

View file

@ -1097,7 +1097,7 @@ func (i *Buffer) Len() int {
// Values of Interop items are not deeply copied.
// It does preserve duplicates only for non-primitive types.
func DeepCopy(item Item) Item {
seen := make(map[Item]Item)
seen := make(map[Item]Item, typicalNumOfItems)
return deepCopy(item, seen)
}

View file

@ -42,7 +42,7 @@ var ErrTooDeep = errors.New("too deep")
// Array, Struct -> array
// Map -> map with keys as UTF-8 bytes
func ToJSON(item Item) ([]byte, error) {
seen := make(map[Item]sliceNoPointer)
seen := make(map[Item]sliceNoPointer, typicalNumOfItems)
return toJSON(nil, seen, item)
}
@ -260,7 +260,7 @@ func (d *decoder) decodeMap() (*Map, error) {
// ToJSONWithTypes serializes any stackitem to JSON in a lossless way.
func ToJSONWithTypes(item Item) ([]byte, error) {
result, err := toJSONWithTypes(item, make(map[Item]bool))
result, err := toJSONWithTypes(item, make(map[Item]bool, typicalNumOfItems))
if err != nil {
return nil, err
}

View file

@ -13,6 +13,12 @@ import (
// (including itself).
const MaxDeserialized = 2048
// typicalNumOfItems is the number of items covering most serializaton needs.
// It's a hint used for map creation, so it's not limiting anything, it's just
// a microoptimization to avoid excessive reallocations. Most of the serialized
// items are structs, so there is at least one of them.
const typicalNumOfItems = 4
// ErrRecursive is returned on attempts to serialize some recursive stack item
// (like array including an item with reference to the same array).
var ErrRecursive = errors.New("recursive item")
@ -40,7 +46,7 @@ type deserContext struct {
func Serialize(item Item) ([]byte, error) {
sc := serContext{
allowInvalid: false,
seen: make(map[Item]sliceNoPointer),
seen: make(map[Item]sliceNoPointer, typicalNumOfItems),
}
err := sc.serialize(item)
if err != nil {
@ -69,7 +75,7 @@ func EncodeBinary(item Item, w *io.BinWriter) {
func EncodeBinaryProtected(item Item, w *io.BinWriter) {
sc := serContext{
allowInvalid: true,
seen: make(map[Item]sliceNoPointer),
seen: make(map[Item]sliceNoPointer, typicalNumOfItems),
}
err := sc.serialize(item)
if err != nil {