5 * Copyright 2014 gRPC authors.
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
27 "github.com/golang/protobuf/proto"
28 "google.golang.org/grpc/test/codec_perf"
31 func setupBenchmarkProtoCodecInputs(b *testing.B, payloadBaseSize uint32) []proto.Message {
32 payloadBase := make([]byte, payloadBaseSize)
33 // arbitrary byte slices
34 payloadSuffixes := [][]byte{
41 protoStructs := make([]proto.Message, 0)
43 for _, p := range payloadSuffixes {
44 ps := &codec_perf.Buffer{}
45 ps.Body = append(payloadBase, p...)
46 protoStructs = append(protoStructs, ps)
52 // The possible use of certain protobuf APIs like the proto.Buffer API potentially involves caching
53 // on our side. This can add checks around memory allocations and possible contention.
54 // Example run: go test -v -run=^$ -bench=BenchmarkProtoCodec -benchmem
55 func BenchmarkProtoCodec(b *testing.B) {
56 // range of message sizes
57 payloadBaseSizes := make([]uint32, 0)
58 for i := uint32(0); i <= 12; i += 4 {
59 payloadBaseSizes = append(payloadBaseSizes, 1<<i)
61 // range of SetParallelism
62 parallelisms := make([]uint32, 0)
63 for i := uint32(0); i <= 16; i += 4 {
64 parallelisms = append(parallelisms, 1<<i)
66 for _, s := range payloadBaseSizes {
67 for _, p := range parallelisms {
68 func(parallelism int, payloadBaseSize uint32) {
69 protoStructs := setupBenchmarkProtoCodecInputs(b, payloadBaseSize)
70 name := fmt.Sprintf("MinPayloadSize:%v/SetParallelism(%v)", payloadBaseSize, parallelism)
71 b.Run(name, func(b *testing.B) {
72 codec := &protoCodec{}
73 b.SetParallelism(parallelism)
74 b.RunParallel(func(pb *testing.PB) {
75 benchmarkProtoCodec(codec, protoStructs, pb, b)
83 func benchmarkProtoCodec(codec *protoCodec, protoStructs []proto.Message, pb *testing.PB, b *testing.B) {
87 ps := protoStructs[counter%len(protoStructs)]
88 fastMarshalAndUnmarshal(codec, ps, b)
92 func fastMarshalAndUnmarshal(protoCodec Codec, protoStruct proto.Message, b *testing.B) {
93 marshaledBytes, err := protoCodec.Marshal(protoStruct)
95 b.Errorf("protoCodec.Marshal(_) returned an error")
97 if err := protoCodec.Unmarshal(marshaledBytes, protoStruct); err != nil {
98 b.Errorf("protoCodec.Unmarshal(_) returned an error")