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