mirror of
https://github.com/protocolbuffers/protobuf-go.git
synced 2025-01-30 12:32:36 +00:00
proto: add examples for Size, MarshalAppend (regarding allocations)
Hopefully this gives users a better understanding of the MarshalAppend entrypoint and what it can be used for, as well as the typical Size usage. Change-Id: I26c9705c3d1dbfea5f30820d41ccabbb88fbb772 Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/573361 Reviewed-by: Lasse Folger <lassefolger@google.com> Auto-Submit: Michael Stapelberg <stapelberg@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Cassondra Foesch <cfoesch@gmail.com> Reviewed-by: Damien Neil <dneil@google.com>
This commit is contained in:
parent
87fded5d2a
commit
55891d73cf
@ -72,7 +72,7 @@ type MarshalOptions struct {
|
||||
|
||||
// Marshal returns the wire-format encoding of m.
|
||||
//
|
||||
// This is the most convenient entry point for encoding a Protobuf message.
|
||||
// This is the most common entry point for encoding a Protobuf message.
|
||||
//
|
||||
// See the [MarshalOptions] type if you need more control.
|
||||
func Marshal(m Message) ([]byte, error) {
|
||||
@ -120,6 +120,9 @@ func emptyBytesForMessage(m Message) []byte {
|
||||
|
||||
// MarshalAppend appends the wire-format encoding of m to b,
|
||||
// returning the result.
|
||||
//
|
||||
// This is a less common entry point than [Marshal], which is only needed if you
|
||||
// need to supply your own buffers for performance reasons.
|
||||
func (o MarshalOptions) MarshalAppend(b []byte, m Message) ([]byte, error) {
|
||||
// Treat nil message interface as an empty message; nothing to append.
|
||||
if m == nil {
|
||||
|
@ -309,3 +309,32 @@ func ExampleMarshal() {
|
||||
// Output: 125ns encoded into 2 bytes of Protobuf wire format:
|
||||
// 10 7d
|
||||
}
|
||||
|
||||
// This example illustrates how to marshal (encode) many Protobuf messages into
|
||||
// wire-format encoding, using the same buffer.
|
||||
//
|
||||
// MarshalAppend will grow the buffer as needed, so over time it will grow large
|
||||
// enough to not need further allocations.
|
||||
//
|
||||
// If unbounded growth of the buffer is undesirable in your application, you can
|
||||
// use [MarshalOptions.Size] to determine a buffer size that is guaranteed to be
|
||||
// large enough for marshaling without allocations.
|
||||
func ExampleMarshalOptions_MarshalAppend_sameBuffer() {
|
||||
var m proto.Message
|
||||
|
||||
opts := proto.MarshalOptions{
|
||||
// set e.g. Deterministic: true, if needed
|
||||
}
|
||||
|
||||
var buf []byte
|
||||
for i := 0; i < 100000; i++ {
|
||||
var err error
|
||||
buf, err = opts.MarshalAppend(buf[:0], m)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
// cap(buf) will grow to hold the largest m.
|
||||
|
||||
// write buf to disk, network, etc.
|
||||
}
|
||||
}
|
||||
|
18
proto/size_test.go
Normal file
18
proto/size_test.go
Normal file
@ -0,0 +1,18 @@
|
||||
// Copyright 2024 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package proto_test
|
||||
|
||||
import (
|
||||
"google.golang.org/protobuf/proto"
|
||||
)
|
||||
|
||||
// Checking if [Size] returns 0 is an easy way to recognize empty messages:
|
||||
func ExampleSize() {
|
||||
var m proto.Message
|
||||
if proto.Size(m) == 0 {
|
||||
// No fields set (or, in proto3, all fields matching the default);
|
||||
// skip processing this message, or return an error, or similar.
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user