~bigbes/tarantool

tarantool-protobuf

ref: b624a6bf75cfdf7ff59c14073e6b1ecc21f9f143 tarantool-protobuf/bench/go/bench_test.go -rw-r--r-- 3.5 KiB
b624a6bf — Eugene Blikh beads: close bgu (ffi.string decode disproven) + memory note on buffer-reuse trap 2 months ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
// Standard `go test -bench=.` benchmarks. Mirrors bench/bench.lua: per
// fixture × per size, encode + decode, throughput + alloc.
//
// Two implementations per case:
//   * apiv2:   google.golang.org/protobuf reflective Marshal/Unmarshal
//              — the default everyone gets out of the box.
//   * vtproto: planetscale/vtprotobuf generated MarshalVT/UnmarshalVT
//              — the fastest pure-Go path, conceptually equivalent to
//              our `mode=full` codegen.
//
// Runs are single-threaded by default (testing.B doesn't parallelize
// unless RunParallel is called).
package bench

import (
	"fmt"
	"testing"

	"google.golang.org/protobuf/proto"

	hellopb "github.com/tarantool-protobuf/bench/go/pb/hellopb"
	proto2pb "github.com/tarantool-protobuf/bench/go/pb/proto2pb"
)

// --- hello.Person ---------------------------------------------------------

func BenchmarkPersonEncode(b *testing.B) {
	for _, sz := range PersonSizes {
		msg := BuildPerson(sz.Target)
		wire, err := proto.Marshal(msg)
		if err != nil {
			b.Fatal(err)
		}

		b.Run(fmt.Sprintf("apiv2/%s", sz.Label), func(b *testing.B) {
			b.SetBytes(int64(len(wire)))
			b.ReportAllocs()
			for i := 0; i < b.N; i++ {
				if _, err := proto.Marshal(msg); err != nil {
					b.Fatal(err)
				}
			}
		})

		b.Run(fmt.Sprintf("vtproto/%s", sz.Label), func(b *testing.B) {
			b.SetBytes(int64(len(wire)))
			b.ReportAllocs()
			for i := 0; i < b.N; i++ {
				if _, err := msg.MarshalVT(); err != nil {
					b.Fatal(err)
				}
			}
		})
	}
}

func BenchmarkPersonDecode(b *testing.B) {
	for _, sz := range PersonSizes {
		msg := BuildPerson(sz.Target)
		wire, err := proto.Marshal(msg)
		if err != nil {
			b.Fatal(err)
		}

		b.Run(fmt.Sprintf("apiv2/%s", sz.Label), func(b *testing.B) {
			b.SetBytes(int64(len(wire)))
			b.ReportAllocs()
			for i := 0; i < b.N; i++ {
				var out hellopb.Person
				if err := proto.Unmarshal(wire, &out); err != nil {
					b.Fatal(err)
				}
			}
		})

		b.Run(fmt.Sprintf("vtproto/%s", sz.Label), func(b *testing.B) {
			b.SetBytes(int64(len(wire)))
			b.ReportAllocs()
			for i := 0; i < b.N; i++ {
				var out hellopb.Person
				if err := out.UnmarshalVT(wire); err != nil {
					b.Fatal(err)
				}
			}
		})
	}
}

// --- proto2_basic.BenchPayload --------------------------------------------

func BenchmarkProto2Encode(b *testing.B) {
	for _, sz := range Proto2Sizes {
		msg := BuildProto2(sz.Target)
		wire, err := proto.Marshal(msg)
		if err != nil {
			b.Fatal(err)
		}

		b.Run(fmt.Sprintf("apiv2/%s", sz.Label), func(b *testing.B) {
			b.SetBytes(int64(len(wire)))
			b.ReportAllocs()
			for i := 0; i < b.N; i++ {
				if _, err := proto.Marshal(msg); err != nil {
					b.Fatal(err)
				}
			}
		})

		// vtproto's generated MarshalVT does not serialize extensions —
		// it skips XXX_unrecognized + protoimpl.ExtensionFields and so
		// drops the ext_count/ext_label payload. The benchmark would
		// produce shorter bytes than apiv2; skip the vtproto variant
		// when the fixture carries extensions so we don't publish
		// misleading throughput numbers.
		_ = msg.MarshalVT // keep symbol referenced; intentionally not benched
	}
}

func BenchmarkProto2Decode(b *testing.B) {
	for _, sz := range Proto2Sizes {
		msg := BuildProto2(sz.Target)
		wire, err := proto.Marshal(msg)
		if err != nil {
			b.Fatal(err)
		}

		b.Run(fmt.Sprintf("apiv2/%s", sz.Label), func(b *testing.B) {
			b.SetBytes(int64(len(wire)))
			b.ReportAllocs()
			for i := 0; i < b.N; i++ {
				var out proto2pb.BenchPayload
				if err := proto.Unmarshal(wire, &out); err != nil {
					b.Fatal(err)
				}
			}
		})
	}
}