Skip to content

Commit

Permalink
Exact slice allocation for repeated packed varints (#480)
Browse files Browse the repository at this point in the history
* Adds a test to verify Unmarshal's memory usage for Varint

Validates #436

* Allocates the exact memory needed for packed repeated varints

Resolves #436

* Add benchmarks for Issue436. We'll test the change against a range of array sizes as well as different varint range.
The before/after tests were made using the same code against fork/master branches.

* Run 'make' with Go 1.11 and protobuf 3.5.1

It seems that combination is somehow special to the CI tooling.
  • Loading branch information
mansimarkaur authored and jmarais committed Sep 14, 2018
1 parent 4aa4cc2 commit 7c690ae
Show file tree
Hide file tree
Showing 12 changed files with 1,833 additions and 213 deletions.
26 changes: 19 additions & 7 deletions plugin/unmarshal/unmarshal.go
Original file line number Diff line number Diff line change
Expand Up @@ -1100,20 +1100,32 @@ func (p *unmarshal) Generate(file *generator.FileDescriptor) {
p.Out()
p.P(`}`)

var fixedTypeSizeBytes int
p.P(`var elementCount int`)
switch *field.Type {
case descriptor.FieldDescriptorProto_TYPE_DOUBLE, descriptor.FieldDescriptorProto_TYPE_FIXED64, descriptor.FieldDescriptorProto_TYPE_SFIXED64:
fixedTypeSizeBytes = 8
p.P(`elementCount = packedLen/`, 8)
case descriptor.FieldDescriptorProto_TYPE_FLOAT, descriptor.FieldDescriptorProto_TYPE_FIXED32, descriptor.FieldDescriptorProto_TYPE_SFIXED32:
fixedTypeSizeBytes = 4
}
if fixedTypeSizeBytes != 0 {
p.P(`if len(m.`, fieldname, `) == 0 {`)
p.P(`elementCount = packedLen/`, 4)
case descriptor.FieldDescriptorProto_TYPE_INT64, descriptor.FieldDescriptorProto_TYPE_UINT64, descriptor.FieldDescriptorProto_TYPE_INT32, descriptor.FieldDescriptorProto_TYPE_UINT32, descriptor.FieldDescriptorProto_TYPE_SINT32, descriptor.FieldDescriptorProto_TYPE_SINT64:
p.P(`var count int`)
p.P(`for _, integer := range dAtA {`)
p.In()
p.P(`if integer < 128 {`)
p.In()
p.P(`m.`, fieldname, ` = make([]`, p.noStarOrSliceType(message, field), `, 0, packedLen/`, fixedTypeSizeBytes, `)`)
p.P(`count++`)
p.Out()
p.P(`}`)
p.Out()
p.P(`}`)
p.P(`elementCount = count`)
case descriptor.FieldDescriptorProto_TYPE_BOOL:
p.P(`elementCount = packedLen`)
}
p.P(`if elementCount != 0 && len(m.`, fieldname, `) == 0 {`)
p.In()
p.P(`m.`, fieldname, ` = make([]`, p.noStarOrSliceType(message, field), `, 0, elementCount)`)
p.Out()
p.P(`}`)

p.P(`for iNdEx < postIndex {`)
p.In()
Expand Down
11 changes: 11 additions & 0 deletions test/casttype/combos/both/casttype.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 11 additions & 0 deletions test/casttype/combos/unmarshaler/casttype.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 7c690ae

Please sign in to comment.