[#376] object: remove pointer from Attribute slice

```
name                           old time/op    new time/op    delta
AttributesMarshal/marshal-8      4.44µs ± 9%    2.72µs ± 0%  -38.79%  (p=0.000 n=10+9)
AttributesMarshal/unmarshal-8    3.16µs ±13%    0.55µs ± 4%  -82.60%  (p=0.000 n=10+10)

name                           old alloc/op   new alloc/op   delta
AttributesMarshal/marshal-8      4.42kB ± 0%    4.42kB ± 0%     ~     (all equal)
AttributesMarshal/unmarshal-8    2.02kB ± 0%    1.79kB ± 0%  -11.11%  (p=0.000 n=10+10)

name                           old allocs/op  new allocs/op  delta
AttributesMarshal/marshal-8        51.0 ± 0%      51.0 ± 0%     ~     (all equal)
AttributesMarshal/unmarshal-8      51.0 ± 0%       1.0 ± 0%  -98.04%  (p=0.000 n=10+10)
```

Signed-off-by: Evgenii Stratonikov <evgeniy@nspcc.ru>
This commit is contained in:
Evgenii Stratonikov 2022-02-28 15:06:51 +03:00 committed by Alex Vanin
parent 204126893e
commit fadd47f4fb
7 changed files with 26 additions and 36 deletions

View file

@ -108,26 +108,20 @@ func WriteNotificationInfo(o *Object, ni NotificationInfo) {
attrs = attrs[:len(attrs)-1] attrs = attrs[:len(attrs)-1]
} }
notifyAttrs := make([]*Attribute, 0, 2)
if !changedEpoch { if !changedEpoch {
eAttr := new(Attribute) index := len(attrs)
eAttr.SetKey(SysAttributeTickEpoch) attrs = append(attrs, Attribute{})
eAttr.SetValue(epoch) attrs[index].SetKey(SysAttributeTickEpoch)
attrs[index].SetValue(epoch)
notifyAttrs = append(notifyAttrs, eAttr)
} }
if !changedTopic && topic != "" { if !changedTopic && topic != "" {
tAttr := new(Attribute) index := len(attrs)
tAttr.SetKey(SysAttributeTickTopic) attrs = append(attrs, Attribute{})
tAttr.SetValue(topic) attrs[index].SetKey(SysAttributeTickTopic)
attrs[index].SetValue(topic)
notifyAttrs = append(notifyAttrs, tAttr)
} }
attrs = append(attrs, notifyAttrs...)
h.SetAttributes(attrs) h.SetAttributes(attrs)
} }

View file

@ -42,7 +42,7 @@ func TestSetNotification(t *testing.T) {
func TestGetNotification(t *testing.T) { func TestGetNotification(t *testing.T) {
o := new(Object) o := new(Object)
attr := []*Attribute{ attr := []Attribute{
{SysAttributeTickEpoch, "10"}, {SysAttributeTickEpoch, "10"},
{SysAttributeTickTopic, "test"}, {SysAttributeTickTopic, "test"},
} }

View file

@ -3,6 +3,8 @@ package object
import ( import (
"math/rand" "math/rand"
"testing" "testing"
"github.com/stretchr/testify/require"
) )
func randString(n int) string { func randString(n int) string {
@ -14,13 +16,13 @@ func randString(n int) string {
} }
func BenchmarkAttributesMarshal(b *testing.B) { func BenchmarkAttributesMarshal(b *testing.B) {
attrs := make([]*Attribute, 50) attrs := make([]Attribute, 50)
for i := range attrs { for i := range attrs {
attrs[i] = new(Attribute)
attrs[i].key = SysAttributePrefix + randString(10) attrs[i].key = SysAttributePrefix + randString(10)
attrs[i].val = randString(10) attrs[i].val = randString(10)
} }
raw := AttributesToGRPC(attrs) raw := AttributesToGRPC(attrs)
require.Equal(b, len(raw), len(attrs))
b.Run("marshal", func(b *testing.B) { b.Run("marshal", func(b *testing.B) {
b.ReportAllocs() b.ReportAllocs()

View file

@ -142,7 +142,7 @@ func (a *Attribute) FromGRPCMessage(m grpc.Message) error {
return nil return nil
} }
func AttributesToGRPC(xs []*Attribute) (res []*object.Header_Attribute) { func AttributesToGRPC(xs []Attribute) (res []*object.Header_Attribute) {
if xs != nil { if xs != nil {
res = make([]*object.Header_Attribute, 0, len(xs)) res = make([]*object.Header_Attribute, 0, len(xs))
@ -154,23 +154,17 @@ func AttributesToGRPC(xs []*Attribute) (res []*object.Header_Attribute) {
return return
} }
func AttributesFromGRPC(xs []*object.Header_Attribute) (res []*Attribute, err error) { func AttributesFromGRPC(xs []*object.Header_Attribute) (res []Attribute, err error) {
if xs != nil { if xs != nil {
res = make([]*Attribute, 0, len(xs)) res = make([]Attribute, len(xs))
for i := range xs { for i := range xs {
var x *Attribute
if xs[i] != nil { if xs[i] != nil {
x = new(Attribute) err = res[i].FromGRPCMessage(xs[i])
err = x.FromGRPCMessage(xs[i])
if err != nil { if err != nil {
return return
} }
} }
res = append(res, x)
} }
} }

View file

@ -394,7 +394,7 @@ func (h *Header) StableMarshal(buf []byte) ([]byte, error) {
offset += n offset += n
for i := range h.attr { for i := range h.attr {
n, err = proto.NestedStructureMarshal(hdrAttributesField, buf[offset:], h.attr[i]) n, err = proto.NestedStructureMarshal(hdrAttributesField, buf[offset:], &h.attr[i])
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -425,7 +425,7 @@ func (h *Header) StableSize() (size int) {
size += proto.NestedStructureSize(hdrHomomorphicHashField, h.homoHash) size += proto.NestedStructureSize(hdrHomomorphicHashField, h.homoHash)
size += proto.NestedStructureSize(hdrSessionTokenField, h.sessionToken) size += proto.NestedStructureSize(hdrSessionTokenField, h.sessionToken)
for i := range h.attr { for i := range h.attr {
size += proto.NestedStructureSize(hdrAttributesField, h.attr[i]) size += proto.NestedStructureSize(hdrAttributesField, &h.attr[i])
} }
size += proto.NestedStructureSize(hdrSplitField, h.split) size += proto.NestedStructureSize(hdrSplitField, h.split)

View file

@ -35,13 +35,13 @@ func GenerateAttribute(empty bool) *object.Attribute {
return m return m
} }
func GenerateAttributes(empty bool) []*object.Attribute { func GenerateAttributes(empty bool) []object.Attribute {
var res []*object.Attribute var res []object.Attribute
if !empty { if !empty {
res = append(res, res = append(res,
GenerateAttribute(false), *GenerateAttribute(false),
GenerateAttribute(false), *GenerateAttribute(false),
) )
} }

View file

@ -56,7 +56,7 @@ type Header struct {
sessionToken *session.Token sessionToken *session.Token
attr []*Attribute attr []Attribute
split *SplitHeader split *SplitHeader
} }
@ -654,7 +654,7 @@ func (h *Header) SetSessionToken(v *session.Token) {
} }
} }
func (h *Header) GetAttributes() []*Attribute { func (h *Header) GetAttributes() []Attribute {
if h != nil { if h != nil {
return h.attr return h.attr
} }
@ -662,7 +662,7 @@ func (h *Header) GetAttributes() []*Attribute {
return nil return nil
} }
func (h *Header) SetAttributes(v []*Attribute) { func (h *Header) SetAttributes(v []Attribute) {
if h != nil { if h != nil {
h.attr = v h.attr = v
} }