1 /*
2 *
3 * Copyright 2017 gRPC authors.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 */
18
19 /* Test out various metadata handling primitives */
20
21 #include <benchmark/benchmark.h>
22 #include <grpc/grpc.h>
23
24 #include "src/core/lib/transport/metadata.h"
25 #include "src/core/lib/transport/static_metadata.h"
26
27 #include "test/cpp/microbenchmarks/helpers.h"
28 #include "test/cpp/util/test_config.h"
29
30 auto& force_library_initialization = Library::get();
31
BM_SliceFromStatic(benchmark::State & state)32 static void BM_SliceFromStatic(benchmark::State& state) {
33 TrackCounters track_counters;
34 while (state.KeepRunning()) {
35 benchmark::DoNotOptimize(grpc_slice_from_static_string("abc"));
36 }
37 track_counters.Finish(state);
38 }
39 BENCHMARK(BM_SliceFromStatic);
40
BM_SliceFromCopied(benchmark::State & state)41 static void BM_SliceFromCopied(benchmark::State& state) {
42 TrackCounters track_counters;
43 while (state.KeepRunning()) {
44 grpc_slice_unref(grpc_slice_from_copied_string("abc"));
45 }
46 track_counters.Finish(state);
47 }
48 BENCHMARK(BM_SliceFromCopied);
49
BM_SliceIntern(benchmark::State & state)50 static void BM_SliceIntern(benchmark::State& state) {
51 TrackCounters track_counters;
52 gpr_slice slice = grpc_slice_from_static_string("abc");
53 while (state.KeepRunning()) {
54 grpc_slice_unref(grpc_slice_intern(slice));
55 }
56 track_counters.Finish(state);
57 }
58 BENCHMARK(BM_SliceIntern);
59
BM_SliceReIntern(benchmark::State & state)60 static void BM_SliceReIntern(benchmark::State& state) {
61 TrackCounters track_counters;
62 gpr_slice slice = grpc_slice_intern(grpc_slice_from_static_string("abc"));
63 while (state.KeepRunning()) {
64 grpc_slice_unref(grpc_slice_intern(slice));
65 }
66 grpc_slice_unref(slice);
67 track_counters.Finish(state);
68 }
69 BENCHMARK(BM_SliceReIntern);
70
BM_SliceInternStaticMetadata(benchmark::State & state)71 static void BM_SliceInternStaticMetadata(benchmark::State& state) {
72 TrackCounters track_counters;
73 while (state.KeepRunning()) {
74 grpc_slice_intern(GRPC_MDSTR_GZIP);
75 }
76 track_counters.Finish(state);
77 }
78 BENCHMARK(BM_SliceInternStaticMetadata);
79
BM_SliceInternEqualToStaticMetadata(benchmark::State & state)80 static void BM_SliceInternEqualToStaticMetadata(benchmark::State& state) {
81 TrackCounters track_counters;
82 gpr_slice slice = grpc_slice_from_static_string("gzip");
83 while (state.KeepRunning()) {
84 grpc_slice_intern(slice);
85 }
86 track_counters.Finish(state);
87 }
88 BENCHMARK(BM_SliceInternEqualToStaticMetadata);
89
BM_MetadataFromNonInternedSlices(benchmark::State & state)90 static void BM_MetadataFromNonInternedSlices(benchmark::State& state) {
91 TrackCounters track_counters;
92 gpr_slice k = grpc_slice_from_static_string("key");
93 gpr_slice v = grpc_slice_from_static_string("value");
94 grpc_core::ExecCtx exec_ctx;
95 while (state.KeepRunning()) {
96 GRPC_MDELEM_UNREF(grpc_mdelem_create(k, v, nullptr));
97 }
98
99 track_counters.Finish(state);
100 }
101 BENCHMARK(BM_MetadataFromNonInternedSlices);
102
BM_MetadataFromInternedSlices(benchmark::State & state)103 static void BM_MetadataFromInternedSlices(benchmark::State& state) {
104 TrackCounters track_counters;
105 gpr_slice k = grpc_slice_intern(grpc_slice_from_static_string("key"));
106 gpr_slice v = grpc_slice_intern(grpc_slice_from_static_string("value"));
107 grpc_core::ExecCtx exec_ctx;
108 while (state.KeepRunning()) {
109 GRPC_MDELEM_UNREF(grpc_mdelem_create(k, v, nullptr));
110 }
111
112 grpc_slice_unref(k);
113 grpc_slice_unref(v);
114 track_counters.Finish(state);
115 }
116 BENCHMARK(BM_MetadataFromInternedSlices);
117
BM_MetadataFromInternedSlicesAlreadyInIndex(benchmark::State & state)118 static void BM_MetadataFromInternedSlicesAlreadyInIndex(
119 benchmark::State& state) {
120 TrackCounters track_counters;
121 gpr_slice k = grpc_slice_intern(grpc_slice_from_static_string("key"));
122 gpr_slice v = grpc_slice_intern(grpc_slice_from_static_string("value"));
123 grpc_core::ExecCtx exec_ctx;
124 grpc_mdelem seed = grpc_mdelem_create(k, v, nullptr);
125 while (state.KeepRunning()) {
126 GRPC_MDELEM_UNREF(grpc_mdelem_create(k, v, nullptr));
127 }
128 GRPC_MDELEM_UNREF(seed);
129
130 grpc_slice_unref(k);
131 grpc_slice_unref(v);
132 track_counters.Finish(state);
133 }
134 BENCHMARK(BM_MetadataFromInternedSlicesAlreadyInIndex);
135
BM_MetadataFromInternedKey(benchmark::State & state)136 static void BM_MetadataFromInternedKey(benchmark::State& state) {
137 TrackCounters track_counters;
138 gpr_slice k = grpc_slice_intern(grpc_slice_from_static_string("key"));
139 gpr_slice v = grpc_slice_from_static_string("value");
140 grpc_core::ExecCtx exec_ctx;
141 while (state.KeepRunning()) {
142 GRPC_MDELEM_UNREF(grpc_mdelem_create(k, v, nullptr));
143 }
144
145 grpc_slice_unref(k);
146 track_counters.Finish(state);
147 }
148 BENCHMARK(BM_MetadataFromInternedKey);
149
BM_MetadataFromNonInternedSlicesWithBackingStore(benchmark::State & state)150 static void BM_MetadataFromNonInternedSlicesWithBackingStore(
151 benchmark::State& state) {
152 TrackCounters track_counters;
153 gpr_slice k = grpc_slice_from_static_string("key");
154 gpr_slice v = grpc_slice_from_static_string("value");
155 char backing_store[sizeof(grpc_mdelem_data)];
156 grpc_core::ExecCtx exec_ctx;
157 while (state.KeepRunning()) {
158 GRPC_MDELEM_UNREF(grpc_mdelem_create(
159 k, v, reinterpret_cast<grpc_mdelem_data*>(backing_store)));
160 }
161
162 track_counters.Finish(state);
163 }
164 BENCHMARK(BM_MetadataFromNonInternedSlicesWithBackingStore);
165
BM_MetadataFromInternedSlicesWithBackingStore(benchmark::State & state)166 static void BM_MetadataFromInternedSlicesWithBackingStore(
167 benchmark::State& state) {
168 TrackCounters track_counters;
169 gpr_slice k = grpc_slice_intern(grpc_slice_from_static_string("key"));
170 gpr_slice v = grpc_slice_intern(grpc_slice_from_static_string("value"));
171 char backing_store[sizeof(grpc_mdelem_data)];
172 grpc_core::ExecCtx exec_ctx;
173 while (state.KeepRunning()) {
174 GRPC_MDELEM_UNREF(grpc_mdelem_create(
175 k, v, reinterpret_cast<grpc_mdelem_data*>(backing_store)));
176 }
177
178 grpc_slice_unref(k);
179 grpc_slice_unref(v);
180 track_counters.Finish(state);
181 }
182 BENCHMARK(BM_MetadataFromInternedSlicesWithBackingStore);
183
BM_MetadataFromInternedKeyWithBackingStore(benchmark::State & state)184 static void BM_MetadataFromInternedKeyWithBackingStore(
185 benchmark::State& state) {
186 TrackCounters track_counters;
187 gpr_slice k = grpc_slice_intern(grpc_slice_from_static_string("key"));
188 gpr_slice v = grpc_slice_from_static_string("value");
189 char backing_store[sizeof(grpc_mdelem_data)];
190 grpc_core::ExecCtx exec_ctx;
191 while (state.KeepRunning()) {
192 GRPC_MDELEM_UNREF(grpc_mdelem_create(
193 k, v, reinterpret_cast<grpc_mdelem_data*>(backing_store)));
194 }
195
196 grpc_slice_unref(k);
197 track_counters.Finish(state);
198 }
199 BENCHMARK(BM_MetadataFromInternedKeyWithBackingStore);
200
BM_MetadataFromStaticMetadataStrings(benchmark::State & state)201 static void BM_MetadataFromStaticMetadataStrings(benchmark::State& state) {
202 TrackCounters track_counters;
203 gpr_slice k = GRPC_MDSTR_STATUS;
204 gpr_slice v = GRPC_MDSTR_200;
205 grpc_core::ExecCtx exec_ctx;
206 while (state.KeepRunning()) {
207 GRPC_MDELEM_UNREF(grpc_mdelem_create(k, v, nullptr));
208 }
209
210 grpc_slice_unref(k);
211 track_counters.Finish(state);
212 }
213 BENCHMARK(BM_MetadataFromStaticMetadataStrings);
214
BM_MetadataFromStaticMetadataStringsNotIndexed(benchmark::State & state)215 static void BM_MetadataFromStaticMetadataStringsNotIndexed(
216 benchmark::State& state) {
217 TrackCounters track_counters;
218 gpr_slice k = GRPC_MDSTR_STATUS;
219 gpr_slice v = GRPC_MDSTR_GZIP;
220 grpc_core::ExecCtx exec_ctx;
221 while (state.KeepRunning()) {
222 GRPC_MDELEM_UNREF(grpc_mdelem_create(k, v, nullptr));
223 }
224
225 grpc_slice_unref(k);
226 track_counters.Finish(state);
227 }
228 BENCHMARK(BM_MetadataFromStaticMetadataStringsNotIndexed);
229
BM_MetadataRefUnrefExternal(benchmark::State & state)230 static void BM_MetadataRefUnrefExternal(benchmark::State& state) {
231 TrackCounters track_counters;
232 char backing_store[sizeof(grpc_mdelem_data)];
233 grpc_core::ExecCtx exec_ctx;
234 grpc_mdelem el = grpc_mdelem_create(
235 grpc_slice_from_static_string("a"), grpc_slice_from_static_string("b"),
236 reinterpret_cast<grpc_mdelem_data*>(backing_store));
237 while (state.KeepRunning()) {
238 GRPC_MDELEM_UNREF(GRPC_MDELEM_REF(el));
239 }
240 GRPC_MDELEM_UNREF(el);
241
242 track_counters.Finish(state);
243 }
244 BENCHMARK(BM_MetadataRefUnrefExternal);
245
BM_MetadataRefUnrefInterned(benchmark::State & state)246 static void BM_MetadataRefUnrefInterned(benchmark::State& state) {
247 TrackCounters track_counters;
248 char backing_store[sizeof(grpc_mdelem_data)];
249 grpc_core::ExecCtx exec_ctx;
250 gpr_slice k = grpc_slice_intern(grpc_slice_from_static_string("key"));
251 gpr_slice v = grpc_slice_intern(grpc_slice_from_static_string("value"));
252 grpc_mdelem el = grpc_mdelem_create(
253 k, v, reinterpret_cast<grpc_mdelem_data*>(backing_store));
254 grpc_slice_unref(k);
255 grpc_slice_unref(v);
256 while (state.KeepRunning()) {
257 GRPC_MDELEM_UNREF(GRPC_MDELEM_REF(el));
258 }
259 GRPC_MDELEM_UNREF(el);
260
261 track_counters.Finish(state);
262 }
263 BENCHMARK(BM_MetadataRefUnrefInterned);
264
BM_MetadataRefUnrefAllocated(benchmark::State & state)265 static void BM_MetadataRefUnrefAllocated(benchmark::State& state) {
266 TrackCounters track_counters;
267 grpc_core::ExecCtx exec_ctx;
268 grpc_mdelem el =
269 grpc_mdelem_create(grpc_slice_from_static_string("a"),
270 grpc_slice_from_static_string("b"), nullptr);
271 while (state.KeepRunning()) {
272 GRPC_MDELEM_UNREF(GRPC_MDELEM_REF(el));
273 }
274 GRPC_MDELEM_UNREF(el);
275
276 track_counters.Finish(state);
277 }
278 BENCHMARK(BM_MetadataRefUnrefAllocated);
279
BM_MetadataRefUnrefStatic(benchmark::State & state)280 static void BM_MetadataRefUnrefStatic(benchmark::State& state) {
281 TrackCounters track_counters;
282 grpc_core::ExecCtx exec_ctx;
283 grpc_mdelem el =
284 grpc_mdelem_create(GRPC_MDSTR_STATUS, GRPC_MDSTR_200, nullptr);
285 while (state.KeepRunning()) {
286 GRPC_MDELEM_UNREF(GRPC_MDELEM_REF(el));
287 }
288 GRPC_MDELEM_UNREF(el);
289
290 track_counters.Finish(state);
291 }
292 BENCHMARK(BM_MetadataRefUnrefStatic);
293
294 // Some distros have RunSpecifiedBenchmarks under the benchmark namespace,
295 // and others do not. This allows us to support both modes.
296 namespace benchmark {
RunTheBenchmarksNamespaced()297 void RunTheBenchmarksNamespaced() { RunSpecifiedBenchmarks(); }
298 } // namespace benchmark
299
main(int argc,char ** argv)300 int main(int argc, char** argv) {
301 ::benchmark::Initialize(&argc, argv);
302 ::grpc::testing::InitTest(&argc, &argv, false);
303 benchmark::RunTheBenchmarksNamespaced();
304 return 0;
305 }
306