...

Source file src/google.golang.org/grpc/encoding/proto/proto_benchmark_test.go

Documentation: google.golang.org/grpc/encoding/proto

     1  /*
     2   *
     3   * Copyright 2014 gRPC authors.
     4   *
     5   * Licensed under the Apache License, Version 2.0 (the "License");
     6   * you may not use this file except in compliance with the License.
     7   * You may obtain a copy of the License at
     8   *
     9   *     http://www.apache.org/licenses/LICENSE-2.0
    10   *
    11   * Unless required by applicable law or agreed to in writing, software
    12   * distributed under the License is distributed on an "AS IS" BASIS,
    13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14   * See the License for the specific language governing permissions and
    15   * limitations under the License.
    16   *
    17   */
    18  
    19  package proto
    20  
    21  import (
    22  	"fmt"
    23  	"testing"
    24  
    25  	"google.golang.org/grpc/encoding"
    26  	"google.golang.org/protobuf/proto"
    27  
    28  	pb "google.golang.org/grpc/test/codec_perf"
    29  )
    30  
    31  func setupBenchmarkProtoCodecInputs(payloadBaseSize uint32) []proto.Message {
    32  	payloadBase := make([]byte, payloadBaseSize)
    33  	// arbitrary byte slices
    34  	payloadSuffixes := [][]byte{
    35  		[]byte("one"),
    36  		[]byte("two"),
    37  		[]byte("three"),
    38  		[]byte("four"),
    39  		[]byte("five"),
    40  	}
    41  	protoStructs := make([]proto.Message, 0)
    42  
    43  	for _, p := range payloadSuffixes {
    44  		ps := &pb.Buffer{}
    45  		ps.Body = append(payloadBase, p...)
    46  		protoStructs = append(protoStructs, ps)
    47  	}
    48  
    49  	return protoStructs
    50  }
    51  
    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)
    60  	}
    61  	// range of SetParallelism
    62  	parallelisms := make([]int, 0)
    63  	for i := uint32(0); i <= 16; i += 4 {
    64  		parallelisms = append(parallelisms, int(1<<i))
    65  	}
    66  	for _, s := range payloadBaseSizes {
    67  		for _, p := range parallelisms {
    68  			protoStructs := setupBenchmarkProtoCodecInputs(s)
    69  			name := fmt.Sprintf("MinPayloadSize:%v/SetParallelism(%v)", s, p)
    70  			b.Run(name, func(b *testing.B) {
    71  				codec := &codec{}
    72  				b.SetParallelism(p)
    73  				b.RunParallel(func(pb *testing.PB) {
    74  					benchmarkProtoCodec(codec, protoStructs, pb, b)
    75  				})
    76  			})
    77  		}
    78  	}
    79  }
    80  
    81  func benchmarkProtoCodec(codec *codec, protoStructs []proto.Message, pb *testing.PB, b *testing.B) {
    82  	counter := 0
    83  	for pb.Next() {
    84  		counter++
    85  		ps := protoStructs[counter%len(protoStructs)]
    86  		fastMarshalAndUnmarshal(codec, ps, b)
    87  	}
    88  }
    89  
    90  func fastMarshalAndUnmarshal(codec encoding.Codec, protoStruct proto.Message, b *testing.B) {
    91  	marshaledBytes, err := codec.Marshal(protoStruct)
    92  	if err != nil {
    93  		b.Errorf("codec.Marshal(_) returned an error")
    94  	}
    95  	res := pb.Buffer{}
    96  	if err := codec.Unmarshal(marshaledBytes, &res); err != nil {
    97  		b.Errorf("codec.Unmarshal(_) returned an error")
    98  	}
    99  }
   100  

View as plain text