Reduce allocations when reusing a Builder.
Add the function `Reset` to the Builder, which facilitates reuse of the underlying byte slice.
This commit is contained in:
parent
ace7fa8094
commit
d756efbf76
|
@ -31,6 +31,15 @@ func NewBuilder(initialSize int) *Builder {
|
|||
return b
|
||||
}
|
||||
|
||||
// Reset truncates the underlying Builder buffer, facilitating alloc-free
|
||||
// reuse of a Builder.
|
||||
func (b *Builder) Reset() {
|
||||
b.Bytes = b.Bytes[:0]
|
||||
b.head = UOffsetT(0)
|
||||
b.minalign = 1
|
||||
b.vtables = b.vtables[:0]
|
||||
}
|
||||
|
||||
// StartObject initializes bookkeeping for writing a new object.
|
||||
func (b *Builder) StartObject(numfields int) {
|
||||
b.notNested()
|
||||
|
@ -155,13 +164,23 @@ func (b *Builder) growByteBuffer() {
|
|||
if (int64(len(b.Bytes)) & int64(0xC0000000)) != 0 {
|
||||
panic("cannot grow buffer beyond 2 gigabytes")
|
||||
}
|
||||
newSize := len(b.Bytes) * 2
|
||||
if newSize == 0 {
|
||||
newSize = 1
|
||||
newLen := len(b.Bytes) * 2
|
||||
if newLen == 0 {
|
||||
newLen = 1
|
||||
}
|
||||
|
||||
if cap(b.Bytes) >= newLen {
|
||||
b.Bytes = b.Bytes[:newLen]
|
||||
} else {
|
||||
extension := make([]byte, newLen-len(b.Bytes))
|
||||
b.Bytes = append(b.Bytes, extension...)
|
||||
}
|
||||
|
||||
middle := newLen / 2
|
||||
copy(b.Bytes[middle:], b.Bytes[:middle])
|
||||
for i := 0 ; i < middle; i++ {
|
||||
b.Bytes[i] = 0
|
||||
}
|
||||
bytes2 := make([]byte, newSize)
|
||||
copy(bytes2[newSize-len(b.Bytes):], b.Bytes)
|
||||
b.Bytes = bytes2
|
||||
}
|
||||
|
||||
// Head gives the start of useful data in the underlying byte buffer.
|
||||
|
|
|
@ -43,7 +43,7 @@ GOPATH=${go_path} go test flatbuffers_test \
|
|||
--test.coverpkg=github.com/google/flatbuffers/go \
|
||||
--cpp_data=${test_dir}/monsterdata_test.mon \
|
||||
--out_data=${test_dir}/monsterdata_go_wire.mon \
|
||||
--test.bench=Build \
|
||||
--test.bench=. \
|
||||
--test.benchtime=3s \
|
||||
--fuzz=true \
|
||||
--fuzz_fields=4 \
|
||||
|
|
|
@ -1254,9 +1254,11 @@ func BenchmarkBuildGold(b *testing.B) {
|
|||
reuse_fred := []byte("Fred")
|
||||
|
||||
b.SetBytes(bytes_length)
|
||||
bldr := flatbuffers.NewBuilder(512)
|
||||
b.ReportAllocs()
|
||||
for i := 0; i < b.N; i++ {
|
||||
bldr := flatbuffers.NewBuilder(0)
|
||||
bldr.Reset()
|
||||
|
||||
str := bldr.CreateByteString(reuse_str)
|
||||
test1 := bldr.CreateByteString(reuse_test1)
|
||||
test2 := bldr.CreateByteString(reuse_test2)
|
||||
|
|
Loading…
Reference in New Issue