README.md
1
2# Protocol Buffers Benchmarks
3
4This directory contains benchmarking schemas and data sets that you
5can use to test a variety of performance scenarios against your
6protobuf language runtime. If you are looking for performance
7numbers of officially supported languages, see [Protobuf Performance](
8https://github.com/protocolbuffers/protobuf/blob/main/docs/performance.md).
9
10## Prerequisite
11
12First, you need to follow the instruction in the root directory's README to
13build your language's protobuf, then:
14
15### CPP
16You need to install [cmake](https://cmake.org/) before building the benchmark.
17
18We are using [google/benchmark](https://github.com/google/benchmark) as the
19benchmark tool for testing cpp. This will be automatically made during build the
20cpp benchmark.
21
22The cpp protobuf performance can be improved by linking with
23[TCMalloc](https://google.github.io/tcmalloc).
24
25### Java
26We're using maven to build the java benchmarks, which is the same as to build
27the Java protobuf. There're no other tools need to install. We're using
28[google/caliper](https://github.com/google/caliper) as benchmark tool, which
29can be automatically included by maven.
30
31### Python
32We're using python C++ API for testing the generated
33CPP proto version of python protobuf, which is also a prerequisite for Python
34protobuf cpp implementation. You need to install the correct version of Python
35C++ extension package before run generated CPP proto version of Python
36protobuf's benchmark. e.g. under Ubuntu, you need to
37
38```
39$ sudo apt-get install python-dev
40$ sudo apt-get install python3-dev
41```
42And you also need to make sure `pkg-config` is installed.
43
44### Go
45Go protobufs are maintained at [github.com/golang/protobuf](
46http://github.com/golang/protobuf). If not done already, you need to install the
47toolchain and the Go protoc-gen-go plugin for protoc.
48
49To install protoc-gen-go, run:
50
51```
52$ go get -u github.com/golang/protobuf/protoc-gen-go
53$ export PATH=$PATH:$(go env GOPATH)/bin
54```
55
56The first command installs `protoc-gen-go` into the `bin` directory in your local `GOPATH`.
57The second command adds the `bin` directory to your `PATH` so that `protoc` can locate the plugin later.
58
59### PHP
60PHP benchmark's requirement is the same as PHP protobuf's requirements. The benchmark will automatically
61include PHP protobuf's src and build the c extension if required.
62
63### Node.js
64Node.js benchmark need [node](https://nodejs.org/en/)(higher than V6) and [npm](https://www.npmjs.com/) package manager installed. This benchmark is using the [benchmark](https://www.npmjs.com/package/benchmark) framework to test, which needn't to manually install. And another prerequisite is [protobuf js](https://github.com/protocolbuffers/protobuf/tree/main/js), which needn't to manually install either
65
66### C#
67The C# benchmark code is built as part of the main Google.Protobuf
68solution. It requires the .NET Core SDK, and depends on
69[BenchmarkDotNet](https://github.com/dotnet/BenchmarkDotNet), which
70will be downloaded automatically.
71
72## Run instructions
73
74To run all the benchmark dataset:
75
76### Java:
77
78First build the Java binary in the usual way with Maven:
79
80```
81$ cd java
82$ mvn install
83```
84
85Assuming that completes successfully,
86
87```
88$ cd ../benchmarks
89$ make java
90```
91
92### CPP:
93
94```
95$ make cpp
96```
97
98For linking with tcmalloc:
99
100```
101$ env LD_PRELOAD={directory to libtcmalloc.so} make cpp
102```
103
104### Python:
105
106We have three versions of python protobuf implementation: pure python, cpp
107reflection and cpp generated code. To run these version benchmark, you need to:
108
109#### Pure Python:
110
111```
112$ make python-pure-python
113```
114
115#### CPP reflection:
116
117```
118$ make python-cpp-reflection
119```
120
121#### CPP generated code:
122
123```
124$ make python-cpp-generated-code
125```
126
127### Go
128```
129$ make go
130```
131
132
133### PHP
134We have two version of php protobuf implementation: pure php, php with c extension. To run these version benchmark, you need to:
135#### Pure PHP
136```
137$ make php
138```
139#### PHP with c extension
140```
141$ make php_c
142```
143
144### Node.js
145```
146$ make js
147```
148
149To run a specific dataset or run with specific options:
150
151### Java:
152
153```
154$ make java-benchmark
155$ ./java-benchmark $(specific generated dataset file name) [$(caliper options)]
156```
157
158### CPP:
159
160```
161$ make cpp-benchmark
162$ ./cpp-benchmark $(specific generated dataset file name) [$(benchmark options)]
163```
164
165### Python:
166
167For Python benchmark we have `--json` for outputting the json result
168
169#### Pure Python:
170
171```
172$ make python-pure-python-benchmark
173$ ./python-pure-python-benchmark [--json] $(specific generated dataset file name)
174```
175
176#### CPP reflection:
177
178```
179$ make python-cpp-reflection-benchmark
180$ ./python-cpp-reflection-benchmark [--json] $(specific generated dataset file name)
181```
182
183#### CPP generated code:
184
185```
186$ make python-cpp-generated-code-benchmark
187$ ./python-cpp-generated-code-benchmark [--json] $(specific generated dataset file name)
188```
189
190### Go:
191```
192$ make go-benchmark
193$ ./go-benchmark $(specific generated dataset file name) [go testing options]
194```
195
196### PHP
197#### Pure PHP
198```
199$ make php-benchmark
200$ ./php-benchmark $(specific generated dataset file name)
201```
202#### PHP with c extension
203```
204$ make php-c-benchmark
205$ ./php-c-benchmark $(specific generated dataset file name)
206```
207
208### Node.js
209```
210$ make js-benchmark
211$ ./js-benchmark $(specific generated dataset file name)
212```
213
214### C#
215From `csharp/src/Google.Protobuf.Benchmarks`, run:
216
217```
218$ dotnet run -c Release
219```
220
221We intend to add support for this within the makefile in due course.
222
223## Benchmark datasets
224
225Each data set is in the format of benchmarks.proto:
226
2271. name is the benchmark dataset's name.
2282. message_name is the benchmark's message type full name (including package and message name)
2293. payload is the list of raw data.
230
231The schema for the datasets is described in `benchmarks.proto`.
232
233Benchmark likely want to run several benchmarks against each data set (parse,
234serialize, possibly JSON, possibly using different APIs, etc).
235
236We would like to add more data sets. In general we will favor data sets
237that make the overall suite diverse without being too large or having
238too many similar tests. Ideally everyone can run through the entire
239suite without the test run getting too long.
240