blob: d181085e74c60aaab4c606671252f83c24b88e19 [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 (
8 "flag"
9 "fmt"
10 "testing"
11
Damien Neil5c5b5312019-05-14 12:44:37 -070012 "google.golang.org/protobuf/encoding/protojson"
13 "google.golang.org/protobuf/encoding/prototext"
Damien Neile89e6242019-05-13 23:55:40 -070014 pref "google.golang.org/protobuf/reflect/protoreflect"
Herbie Ong8eba9ee2019-04-15 15:29:50 -070015
Damien Neile89e6242019-05-13 23:55:40 -070016 tpb "google.golang.org/protobuf/internal/testprotos/test"
Herbie Ong8eba9ee2019-04-15 15:29:50 -070017)
18
19// The results of these microbenchmarks are unlikely to correspond well
20// to real world peformance. They are mainly useful as a quick check to
21// detect unexpected regressions and for profiling specific cases.
22
23var benchV1 = flag.Bool("v1", false, "benchmark the v1 implementation")
24
Joe Tsai84177c92019-09-17 13:38:48 -070025const maxRecurseLevel = 3
Herbie Ong8eba9ee2019-04-15 15:29:50 -070026
27func makeProto() *tpb.TestAllTypes {
28 m := &tpb.TestAllTypes{}
29 fillMessage(m.ProtoReflect(), 0)
30 return m
31}
32
33func fillMessage(m pref.Message, level int) {
34 if level > maxRecurseLevel {
35 return
36 }
37
Joe Tsai0fc49f82019-05-01 12:29:25 -070038 fieldDescs := m.Descriptor().Fields()
Herbie Ong8eba9ee2019-04-15 15:29:50 -070039 for i := 0; i < fieldDescs.Len(); i++ {
40 fd := fieldDescs.Get(i)
Joe Tsaiac31a352019-05-13 14:32:56 -070041 switch {
42 case fd.IsList():
Joe Tsai378c1322019-04-25 23:48:08 -070043 setList(m.Mutable(fd).List(), fd, level)
Joe Tsaiac31a352019-05-13 14:32:56 -070044 case fd.IsMap():
Joe Tsai378c1322019-04-25 23:48:08 -070045 setMap(m.Mutable(fd).Map(), fd, level)
Joe Tsaiac31a352019-05-13 14:32:56 -070046 default:
Joe Tsai378c1322019-04-25 23:48:08 -070047 setScalarField(m, fd, level)
Herbie Ong8eba9ee2019-04-15 15:29:50 -070048 }
49 }
50}
51
Joe Tsai378c1322019-04-25 23:48:08 -070052func setScalarField(m pref.Message, fd pref.FieldDescriptor, level int) {
Herbie Ong8eba9ee2019-04-15 15:29:50 -070053 switch fd.Kind() {
54 case pref.MessageKind, pref.GroupKind:
Damien Neild91c4222019-09-04 10:46:00 -070055 val := m.NewField(fd)
56 fillMessage(val.Message(), level+1)
57 m.Set(fd, val)
Herbie Ong8eba9ee2019-04-15 15:29:50 -070058 default:
Joe Tsai378c1322019-04-25 23:48:08 -070059 m.Set(fd, scalarField(fd.Kind()))
Herbie Ong8eba9ee2019-04-15 15:29:50 -070060 }
61}
62
63func scalarField(kind pref.Kind) pref.Value {
64 switch kind {
65 case pref.BoolKind:
Joe Tsai84177c92019-09-17 13:38:48 -070066 return pref.ValueOfBool(true)
Herbie Ong8eba9ee2019-04-15 15:29:50 -070067
68 case pref.Int32Kind, pref.Sint32Kind, pref.Sfixed32Kind:
Joe Tsai84177c92019-09-17 13:38:48 -070069 return pref.ValueOfInt32(1 << 30)
Herbie Ong8eba9ee2019-04-15 15:29:50 -070070
71 case pref.Int64Kind, pref.Sint64Kind, pref.Sfixed64Kind:
Joe Tsai84177c92019-09-17 13:38:48 -070072 return pref.ValueOfInt64(1 << 30)
Herbie Ong8eba9ee2019-04-15 15:29:50 -070073
74 case pref.Uint32Kind, pref.Fixed32Kind:
Joe Tsai84177c92019-09-17 13:38:48 -070075 return pref.ValueOfUint32(1 << 30)
Herbie Ong8eba9ee2019-04-15 15:29:50 -070076
77 case pref.Uint64Kind, pref.Fixed64Kind:
Joe Tsai84177c92019-09-17 13:38:48 -070078 return pref.ValueOfUint64(1 << 30)
Herbie Ong8eba9ee2019-04-15 15:29:50 -070079
80 case pref.FloatKind:
Joe Tsai84177c92019-09-17 13:38:48 -070081 return pref.ValueOfFloat32(3.14159265)
Herbie Ong8eba9ee2019-04-15 15:29:50 -070082
83 case pref.DoubleKind:
Joe Tsai84177c92019-09-17 13:38:48 -070084 return pref.ValueOfFloat64(3.14159265)
Herbie Ong8eba9ee2019-04-15 15:29:50 -070085
86 case pref.BytesKind:
Joe Tsai84177c92019-09-17 13:38:48 -070087 return pref.ValueOfBytes([]byte("hello world"))
Herbie Ong8eba9ee2019-04-15 15:29:50 -070088
89 case pref.StringKind:
Joe Tsai84177c92019-09-17 13:38:48 -070090 return pref.ValueOfString("hello world")
Herbie Ong8eba9ee2019-04-15 15:29:50 -070091
92 case pref.EnumKind:
Joe Tsai84177c92019-09-17 13:38:48 -070093 return pref.ValueOfEnum(42)
Herbie Ong8eba9ee2019-04-15 15:29:50 -070094 }
95
96 panic(fmt.Sprintf("FieldDescriptor.Kind %v is not valid", kind))
97}
98
99func setList(list pref.List, fd pref.FieldDescriptor, level int) {
100 switch fd.Kind() {
101 case pref.MessageKind, pref.GroupKind:
102 for i := 0; i < 10; i++ {
Damien Neild91c4222019-09-04 10:46:00 -0700103 val := list.NewElement()
104 fillMessage(val.Message(), level+1)
105 list.Append(val)
Herbie Ong8eba9ee2019-04-15 15:29:50 -0700106 }
107 default:
108 for i := 0; i < 100; i++ {
109 list.Append(scalarField(fd.Kind()))
110 }
111 }
112}
113
114func setMap(mmap pref.Map, fd pref.FieldDescriptor, level int) {
Joe Tsaid24bc722019-04-15 23:39:09 -0700115 fields := fd.Message().Fields()
Herbie Ong8eba9ee2019-04-15 15:29:50 -0700116 keyDesc := fields.ByNumber(1)
117 valDesc := fields.ByNumber(2)
118
119 pkey := scalarField(keyDesc.Kind())
120 switch kind := valDesc.Kind(); kind {
121 case pref.MessageKind, pref.GroupKind:
Damien Neild91c4222019-09-04 10:46:00 -0700122 val := mmap.NewValue()
123 fillMessage(val.Message(), level+1)
124 mmap.Set(pkey.MapKey(), val)
Herbie Ong8eba9ee2019-04-15 15:29:50 -0700125 default:
126 mmap.Set(pkey.MapKey(), scalarField(kind))
127 }
128}
129
130func BenchmarkTextEncode(b *testing.B) {
131 m := makeProto()
132 for i := 0; i < b.N; i++ {
Damien Neilec00e322020-01-09 09:23:52 -0800133 _, err := prototext.MarshalOptions{Indent: " "}.Marshal(m)
134 if err != nil {
135 b.Fatal(err)
Herbie Ong8eba9ee2019-04-15 15:29:50 -0700136 }
137 }
138}
139
140func BenchmarkTextDecode(b *testing.B) {
141 m := makeProto()
Damien Neil5c5b5312019-05-14 12:44:37 -0700142 in, err := prototext.MarshalOptions{Indent: " "}.Marshal(m)
Herbie Ong8eba9ee2019-04-15 15:29:50 -0700143 if err != nil {
144 b.Fatal(err)
145 }
146
147 for i := 0; i < b.N; i++ {
148 m := &tpb.TestAllTypes{}
Damien Neilec00e322020-01-09 09:23:52 -0800149 if err := prototext.Unmarshal(in, m); err != nil {
Herbie Ong8eba9ee2019-04-15 15:29:50 -0700150 b.Fatal(err)
151 }
152 }
153}
154
155func BenchmarkJSONEncode(b *testing.B) {
156 m := makeProto()
157 for i := 0; i < b.N; i++ {
Damien Neilec00e322020-01-09 09:23:52 -0800158 _, err := protojson.MarshalOptions{Indent: " "}.Marshal(m)
Herbie Ong8eba9ee2019-04-15 15:29:50 -0700159 if err != nil {
160 b.Fatal(err)
161 }
162 }
163}
164
165func BenchmarkJSONDecode(b *testing.B) {
166 m := makeProto()
Damien Neil5c5b5312019-05-14 12:44:37 -0700167 out, err := protojson.MarshalOptions{Indent: " "}.Marshal(m)
Herbie Ong8eba9ee2019-04-15 15:29:50 -0700168 if err != nil {
169 b.Fatal(err)
170 }
171
172 for i := 0; i < b.N; i++ {
173 m := &tpb.TestAllTypes{}
Damien Neilec00e322020-01-09 09:23:52 -0800174 if err := protojson.Unmarshal(out, m); err != nil {
Herbie Ong8eba9ee2019-04-15 15:29:50 -0700175 b.Fatal(err)
176 }
177 }
178}