xref: /aosp_15_r20/external/golang-protobuf/encoding/bench_test.go (revision 1c12ee1efe575feb122dbf939ff15148a3b3e8f2)
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