blob: 490656b3086abc92194b16ae15521a7268ffd520 [file] [log] [blame]
Herbie Ong8eba9ee2019-04-15 15:29:50 -07001// 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
5package encoding_test
6
7import (
Herbie Ong8eba9ee2019-04-15 15:29:50 -07008 "fmt"
9 "testing"
10
Damien Neil5c5b5312019-05-14 12:44:37 -070011 "google.golang.org/protobuf/encoding/protojson"
12 "google.golang.org/protobuf/encoding/prototext"
Damien Neile89e6242019-05-13 23:55:40 -070013 pref "google.golang.org/protobuf/reflect/protoreflect"
Herbie Ong8eba9ee2019-04-15 15:29:50 -070014
Damien Neile89e6242019-05-13 23:55:40 -070015 tpb "google.golang.org/protobuf/internal/testprotos/test"
Herbie Ong8eba9ee2019-04-15 15:29:50 -070016)
17
18// The results of these microbenchmarks are unlikely to correspond well
19// to real world peformance. They are mainly useful as a quick check to
20// detect unexpected regressions and for profiling specific cases.
21
Joe Tsai84177c92019-09-17 13:38:48 -070022const maxRecurseLevel = 3
Herbie Ong8eba9ee2019-04-15 15:29:50 -070023
24func makeProto() *tpb.TestAllTypes {
25 m := &tpb.TestAllTypes{}
26 fillMessage(m.ProtoReflect(), 0)
27 return m
28}
29
30func fillMessage(m pref.Message, level int) {
31 if level > maxRecurseLevel {
32 return
33 }
34
Joe Tsai0fc49f82019-05-01 12:29:25 -070035 fieldDescs := m.Descriptor().Fields()
Herbie Ong8eba9ee2019-04-15 15:29:50 -070036 for i := 0; i < fieldDescs.Len(); i++ {
37 fd := fieldDescs.Get(i)
Joe Tsaiac31a352019-05-13 14:32:56 -070038 switch {
39 case fd.IsList():
Joe Tsai378c1322019-04-25 23:48:08 -070040 setList(m.Mutable(fd).List(), fd, level)
Joe Tsaiac31a352019-05-13 14:32:56 -070041 case fd.IsMap():
Joe Tsai378c1322019-04-25 23:48:08 -070042 setMap(m.Mutable(fd).Map(), fd, level)
Joe Tsaiac31a352019-05-13 14:32:56 -070043 default:
Joe Tsai378c1322019-04-25 23:48:08 -070044 setScalarField(m, fd, level)
Herbie Ong8eba9ee2019-04-15 15:29:50 -070045 }
46 }
47}
48
Joe Tsai378c1322019-04-25 23:48:08 -070049func setScalarField(m pref.Message, fd pref.FieldDescriptor, level int) {
Herbie Ong8eba9ee2019-04-15 15:29:50 -070050 switch fd.Kind() {
51 case pref.MessageKind, pref.GroupKind:
Damien Neild91c4222019-09-04 10:46:00 -070052 val := m.NewField(fd)
53 fillMessage(val.Message(), level+1)
54 m.Set(fd, val)
Herbie Ong8eba9ee2019-04-15 15:29:50 -070055 default:
Joe Tsai378c1322019-04-25 23:48:08 -070056 m.Set(fd, scalarField(fd.Kind()))
Herbie Ong8eba9ee2019-04-15 15:29:50 -070057 }
58}
59
60func scalarField(kind pref.Kind) pref.Value {
61 switch kind {
62 case pref.BoolKind:
Joe Tsai84177c92019-09-17 13:38:48 -070063 return pref.ValueOfBool(true)
Herbie Ong8eba9ee2019-04-15 15:29:50 -070064
65 case pref.Int32Kind, pref.Sint32Kind, pref.Sfixed32Kind:
Joe Tsai84177c92019-09-17 13:38:48 -070066 return pref.ValueOfInt32(1 << 30)
Herbie Ong8eba9ee2019-04-15 15:29:50 -070067
68 case pref.Int64Kind, pref.Sint64Kind, pref.Sfixed64Kind:
Joe Tsai84177c92019-09-17 13:38:48 -070069 return pref.ValueOfInt64(1 << 30)
Herbie Ong8eba9ee2019-04-15 15:29:50 -070070
71 case pref.Uint32Kind, pref.Fixed32Kind:
Joe Tsai84177c92019-09-17 13:38:48 -070072 return pref.ValueOfUint32(1 << 30)
Herbie Ong8eba9ee2019-04-15 15:29:50 -070073
74 case pref.Uint64Kind, pref.Fixed64Kind:
Joe Tsai84177c92019-09-17 13:38:48 -070075 return pref.ValueOfUint64(1 << 30)
Herbie Ong8eba9ee2019-04-15 15:29:50 -070076
77 case pref.FloatKind:
Joe Tsai84177c92019-09-17 13:38:48 -070078 return pref.ValueOfFloat32(3.14159265)
Herbie Ong8eba9ee2019-04-15 15:29:50 -070079
80 case pref.DoubleKind:
Joe Tsai84177c92019-09-17 13:38:48 -070081 return pref.ValueOfFloat64(3.14159265)
Herbie Ong8eba9ee2019-04-15 15:29:50 -070082
83 case pref.BytesKind:
Joe Tsai84177c92019-09-17 13:38:48 -070084 return pref.ValueOfBytes([]byte("hello world"))
Herbie Ong8eba9ee2019-04-15 15:29:50 -070085
86 case pref.StringKind:
Joe Tsai84177c92019-09-17 13:38:48 -070087 return pref.ValueOfString("hello world")
Herbie Ong8eba9ee2019-04-15 15:29:50 -070088
89 case pref.EnumKind:
Joe Tsai84177c92019-09-17 13:38:48 -070090 return pref.ValueOfEnum(42)
Herbie Ong8eba9ee2019-04-15 15:29:50 -070091 }
92
93 panic(fmt.Sprintf("FieldDescriptor.Kind %v is not valid", kind))
94}
95
96func setList(list pref.List, fd pref.FieldDescriptor, level int) {
97 switch fd.Kind() {
98 case pref.MessageKind, pref.GroupKind:
99 for i := 0; i < 10; i++ {
Damien Neild91c4222019-09-04 10:46:00 -0700100 val := list.NewElement()
101 fillMessage(val.Message(), level+1)
102 list.Append(val)
Herbie Ong8eba9ee2019-04-15 15:29:50 -0700103 }
104 default:
105 for i := 0; i < 100; i++ {
106 list.Append(scalarField(fd.Kind()))
107 }
108 }
109}
110
111func setMap(mmap pref.Map, fd pref.FieldDescriptor, level int) {
Joe Tsaid24bc722019-04-15 23:39:09 -0700112 fields := fd.Message().Fields()
Herbie Ong8eba9ee2019-04-15 15:29:50 -0700113 keyDesc := fields.ByNumber(1)
114 valDesc := fields.ByNumber(2)
115
116 pkey := scalarField(keyDesc.Kind())
117 switch kind := valDesc.Kind(); kind {
118 case pref.MessageKind, pref.GroupKind:
Damien Neild91c4222019-09-04 10:46:00 -0700119 val := mmap.NewValue()
120 fillMessage(val.Message(), level+1)
121 mmap.Set(pkey.MapKey(), val)
Herbie Ong8eba9ee2019-04-15 15:29:50 -0700122 default:
123 mmap.Set(pkey.MapKey(), scalarField(kind))
124 }
125}
126
127func BenchmarkTextEncode(b *testing.B) {
128 m := makeProto()
129 for i := 0; i < b.N; i++ {
Damien Neilec00e322020-01-09 09:23:52 -0800130 _, err := prototext.MarshalOptions{Indent: " "}.Marshal(m)
131 if err != nil {
132 b.Fatal(err)
Herbie Ong8eba9ee2019-04-15 15:29:50 -0700133 }
134 }
135}
136
137func BenchmarkTextDecode(b *testing.B) {
138 m := makeProto()
Damien Neil5c5b5312019-05-14 12:44:37 -0700139 in, err := prototext.MarshalOptions{Indent: " "}.Marshal(m)
Herbie Ong8eba9ee2019-04-15 15:29:50 -0700140 if err != nil {
141 b.Fatal(err)
142 }
143
144 for i := 0; i < b.N; i++ {
145 m := &tpb.TestAllTypes{}
Damien Neilec00e322020-01-09 09:23:52 -0800146 if err := prototext.Unmarshal(in, m); err != nil {
Herbie Ong8eba9ee2019-04-15 15:29:50 -0700147 b.Fatal(err)
148 }
149 }
150}
151
152func BenchmarkJSONEncode(b *testing.B) {
153 m := makeProto()
154 for i := 0; i < b.N; i++ {
Damien Neilec00e322020-01-09 09:23:52 -0800155 _, err := protojson.MarshalOptions{Indent: " "}.Marshal(m)
Herbie Ong8eba9ee2019-04-15 15:29:50 -0700156 if err != nil {
157 b.Fatal(err)
158 }
159 }
160}
161
162func BenchmarkJSONDecode(b *testing.B) {
163 m := makeProto()
Damien Neil5c5b5312019-05-14 12:44:37 -0700164 out, err := protojson.MarshalOptions{Indent: " "}.Marshal(m)
Herbie Ong8eba9ee2019-04-15 15:29:50 -0700165 if err != nil {
166 b.Fatal(err)
167 }
168
169 for i := 0; i < b.N; i++ {
170 m := &tpb.TestAllTypes{}
Damien Neilec00e322020-01-09 09:23:52 -0800171 if err := protojson.Unmarshal(out, m); err != nil {
Herbie Ong8eba9ee2019-04-15 15:29:50 -0700172 b.Fatal(err)
173 }
174 }
175}