github.com/whiteCcinn/protobuf-go@v1.0.9/encoding/bench_test.go (about) 1 // Copyright 2018 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package encoding_test 6 7 import ( 8 "fmt" 9 "testing" 10 11 "github.com/whiteCcinn/protobuf-go/encoding/protojson" 12 "github.com/whiteCcinn/protobuf-go/encoding/prototext" 13 "github.com/whiteCcinn/protobuf-go/reflect/protoreflect" 14 15 tpb "github.com/whiteCcinn/protobuf-go/internal/testprotos/test" 16 ) 17 18 // The results of these microbenchmarks are unlikely to correspond well 19 // to real world performance. They are mainly useful as a quick check to 20 // detect unexpected regressions and for profiling specific cases. 21 22 const maxRecurseLevel = 3 23 24 func makeProto() *tpb.TestAllTypes { 25 m := &tpb.TestAllTypes{} 26 fillMessage(m.ProtoReflect(), 0) 27 return m 28 } 29 30 func fillMessage(m protoreflect.Message, level int) { 31 if level > maxRecurseLevel { 32 return 33 } 34 35 fieldDescs := m.Descriptor().Fields() 36 for i := 0; i < fieldDescs.Len(); i++ { 37 fd := fieldDescs.Get(i) 38 switch { 39 case fd.IsList(): 40 setList(m.Mutable(fd).List(), fd, level) 41 case fd.IsMap(): 42 setMap(m.Mutable(fd).Map(), fd, level) 43 default: 44 setScalarField(m, fd, level) 45 } 46 } 47 } 48 49 func setScalarField(m protoreflect.Message, fd protoreflect.FieldDescriptor, level int) { 50 switch fd.Kind() { 51 case protoreflect.MessageKind, protoreflect.GroupKind: 52 val := m.NewField(fd) 53 fillMessage(val.Message(), level+1) 54 m.Set(fd, val) 55 default: 56 m.Set(fd, scalarField(fd.Kind())) 57 } 58 } 59 60 func scalarField(kind protoreflect.Kind) protoreflect.Value { 61 switch kind { 62 case protoreflect.BoolKind: 63 return protoreflect.ValueOfBool(true) 64 65 case protoreflect.Int32Kind, protoreflect.Sint32Kind, protoreflect.Sfixed32Kind: 66 return protoreflect.ValueOfInt32(1 << 30) 67 68 case protoreflect.Int64Kind, protoreflect.Sint64Kind, protoreflect.Sfixed64Kind: 69 return protoreflect.ValueOfInt64(1 << 30) 70 71 case protoreflect.Uint32Kind, protoreflect.Fixed32Kind: 72 return protoreflect.ValueOfUint32(1 << 30) 73 74 case protoreflect.Uint64Kind, protoreflect.Fixed64Kind: 75 return protoreflect.ValueOfUint64(1 << 30) 76 77 case protoreflect.FloatKind: 78 return protoreflect.ValueOfFloat32(3.14159265) 79 80 case protoreflect.DoubleKind: 81 return protoreflect.ValueOfFloat64(3.14159265) 82 83 case protoreflect.BytesKind: 84 return protoreflect.ValueOfBytes([]byte("hello world")) 85 86 case protoreflect.StringKind: 87 return protoreflect.ValueOfString("hello world") 88 89 case protoreflect.EnumKind: 90 return protoreflect.ValueOfEnum(42) 91 } 92 93 panic(fmt.Sprintf("FieldDescriptor.Kind %v is not valid", kind)) 94 } 95 96 func setList(list protoreflect.List, fd protoreflect.FieldDescriptor, level int) { 97 switch fd.Kind() { 98 case protoreflect.MessageKind, protoreflect.GroupKind: 99 for i := 0; i < 10; i++ { 100 val := list.NewElement() 101 fillMessage(val.Message(), level+1) 102 list.Append(val) 103 } 104 default: 105 for i := 0; i < 100; i++ { 106 list.Append(scalarField(fd.Kind())) 107 } 108 } 109 } 110 111 func setMap(mmap protoreflect.Map, fd protoreflect.FieldDescriptor, level int) { 112 fields := fd.Message().Fields() 113 keyDesc := fields.ByNumber(1) 114 valDesc := fields.ByNumber(2) 115 116 pkey := scalarField(keyDesc.Kind()) 117 switch kind := valDesc.Kind(); kind { 118 case protoreflect.MessageKind, protoreflect.GroupKind: 119 val := mmap.NewValue() 120 fillMessage(val.Message(), level+1) 121 mmap.Set(pkey.MapKey(), val) 122 default: 123 mmap.Set(pkey.MapKey(), scalarField(kind)) 124 } 125 } 126 127 func BenchmarkTextEncode(b *testing.B) { 128 m := makeProto() 129 for i := 0; i < b.N; i++ { 130 _, err := prototext.MarshalOptions{Indent: " "}.Marshal(m) 131 if err != nil { 132 b.Fatal(err) 133 } 134 } 135 } 136 137 func BenchmarkTextDecode(b *testing.B) { 138 m := makeProto() 139 in, err := prototext.MarshalOptions{Indent: " "}.Marshal(m) 140 if err != nil { 141 b.Fatal(err) 142 } 143 144 for i := 0; i < b.N; i++ { 145 m := &tpb.TestAllTypes{} 146 if err := prototext.Unmarshal(in, m); err != nil { 147 b.Fatal(err) 148 } 149 } 150 } 151 152 func BenchmarkJSONEncode(b *testing.B) { 153 m := makeProto() 154 for i := 0; i < b.N; i++ { 155 _, err := protojson.MarshalOptions{Indent: " "}.Marshal(m) 156 if err != nil { 157 b.Fatal(err) 158 } 159 } 160 } 161 162 func BenchmarkJSONDecode(b *testing.B) { 163 m := makeProto() 164 out, err := protojson.MarshalOptions{Indent: " "}.Marshal(m) 165 if err != nil { 166 b.Fatal(err) 167 } 168 169 for i := 0; i < b.N; i++ { 170 m := &tpb.TestAllTypes{} 171 if err := protojson.Unmarshal(out, m); err != nil { 172 b.Fatal(err) 173 } 174 } 175 }