gitee.com/ks-custle/core-gm@v0.0.0-20230922171213-b83bdd97b62c/grpc/encoding/proto/proto_benchmark_test.go (about) 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 "gitee.com/ks-custle/core-gm/grpc/encoding" 26 "gitee.com/ks-custle/core-gm/grpc/test/codec_perf" 27 "github.com/golang/protobuf/proto" 28 ) 29 30 func setupBenchmarkProtoCodecInputs(payloadBaseSize uint32) []proto.Message { 31 payloadBase := make([]byte, payloadBaseSize) 32 // arbitrary byte slices 33 payloadSuffixes := [][]byte{ 34 []byte("one"), 35 []byte("two"), 36 []byte("three"), 37 []byte("four"), 38 []byte("five"), 39 } 40 protoStructs := make([]proto.Message, 0) 41 42 for _, p := range payloadSuffixes { 43 ps := &codec_perf.Buffer{} 44 ps.Body = append(payloadBase, p...) 45 protoStructs = append(protoStructs, ps) 46 } 47 48 return protoStructs 49 } 50 51 // The possible use of certain protobuf APIs like the proto.Buffer API potentially involves caching 52 // on our side. This can add checks around memory allocations and possible contention. 53 // Example run: go test -v -run=^$ -bench=BenchmarkProtoCodec -benchmem 54 func BenchmarkProtoCodec(b *testing.B) { 55 // range of message sizes 56 payloadBaseSizes := make([]uint32, 0) 57 for i := uint32(0); i <= 12; i += 4 { 58 payloadBaseSizes = append(payloadBaseSizes, 1<<i) 59 } 60 // range of SetParallelism 61 parallelisms := make([]int, 0) 62 for i := uint32(0); i <= 16; i += 4 { 63 parallelisms = append(parallelisms, int(1<<i)) 64 } 65 for _, s := range payloadBaseSizes { 66 for _, p := range parallelisms { 67 protoStructs := setupBenchmarkProtoCodecInputs(s) 68 name := fmt.Sprintf("MinPayloadSize:%v/SetParallelism(%v)", s, p) 69 b.Run(name, func(b *testing.B) { 70 codec := &codec{} 71 b.SetParallelism(p) 72 b.RunParallel(func(pb *testing.PB) { 73 benchmarkProtoCodec(codec, protoStructs, pb, b) 74 }) 75 }) 76 } 77 } 78 } 79 80 func benchmarkProtoCodec(codec *codec, protoStructs []proto.Message, pb *testing.PB, b *testing.B) { 81 counter := 0 82 for pb.Next() { 83 counter++ 84 ps := protoStructs[counter%len(protoStructs)] 85 fastMarshalAndUnmarshal(codec, ps, b) 86 } 87 } 88 89 func fastMarshalAndUnmarshal(codec encoding.Codec, protoStruct proto.Message, b *testing.B) { 90 marshaledBytes, err := codec.Marshal(protoStruct) 91 if err != nil { 92 b.Errorf("codec.Marshal(_) returned an error") 93 } 94 res := codec_perf.Buffer{} 95 if err := codec.Unmarshal(marshaledBytes, &res); err != nil { 96 b.Errorf("codec.Unmarshal(_) returned an error") 97 } 98 }