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/slice/slice_internal.h"
25 #include "src/core/lib/transport/metadata.h"
26 #include "src/core/lib/transport/static_metadata.h"
27
28 #include "test/core/util/test_config.h"
29 #include "test/cpp/microbenchmarks/helpers.h"
30 #include "test/cpp/util/test_config.h"
31
BM_SliceFromStatic(benchmark::State & state)32 static void BM_SliceFromStatic(benchmark::State& state) {
33 TrackCounters track_counters;
34 for (auto _ : state) {
35 benchmark::DoNotOptimize(grpc_core::ExternallyManagedSlice("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 for (auto _ : state) {
44 grpc_slice_unref(grpc_core::UnmanagedMemorySlice("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 grpc_core::ExternallyManagedSlice slice("abc");
53 for (auto _ : state) {
54 grpc_slice_unref(grpc_core::ManagedMemorySlice(&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 grpc_core::ExternallyManagedSlice static_slice("abc");
63 grpc_core::ManagedMemorySlice slice(&static_slice);
64 for (auto _ : state) {
65 grpc_slice_unref(grpc_core::ManagedMemorySlice(&slice));
66 }
67 grpc_slice_unref(slice);
68 track_counters.Finish(state);
69 }
70 BENCHMARK(BM_SliceReIntern);
71
BM_SliceInternStaticMetadata(benchmark::State & state)72 static void BM_SliceInternStaticMetadata(benchmark::State& state) {
73 TrackCounters track_counters;
74 for (auto _ : state) {
75 benchmark::DoNotOptimize(grpc_core::ManagedMemorySlice(&GRPC_MDSTR_GZIP));
76 }
77 track_counters.Finish(state);
78 }
79 BENCHMARK(BM_SliceInternStaticMetadata);
80
BM_SliceInternEqualToStaticMetadata(benchmark::State & state)81 static void BM_SliceInternEqualToStaticMetadata(benchmark::State& state) {
82 TrackCounters track_counters;
83 grpc_core::ExternallyManagedSlice slice("gzip");
84 for (auto _ : state) {
85 benchmark::DoNotOptimize(grpc_core::ManagedMemorySlice(&slice));
86 }
87 track_counters.Finish(state);
88 }
89 BENCHMARK(BM_SliceInternEqualToStaticMetadata);
90
BM_MetadataFromNonInternedSlices(benchmark::State & state)91 static void BM_MetadataFromNonInternedSlices(benchmark::State& state) {
92 TrackCounters track_counters;
93 grpc_core::ExternallyManagedSlice k("key");
94 grpc_core::ExternallyManagedSlice v("value");
95 grpc_core::ExecCtx exec_ctx;
96 for (auto _ : state) {
97 GRPC_MDELEM_UNREF(grpc_mdelem_create(k, v, nullptr));
98 }
99
100 track_counters.Finish(state);
101 }
102 BENCHMARK(BM_MetadataFromNonInternedSlices);
103
BM_MetadataFromInternedSlices(benchmark::State & state)104 static void BM_MetadataFromInternedSlices(benchmark::State& state) {
105 TrackCounters track_counters;
106 grpc_core::ManagedMemorySlice k("key");
107 grpc_core::ManagedMemorySlice v("value");
108 grpc_core::ExecCtx exec_ctx;
109 for (auto _ : state) {
110 GRPC_MDELEM_UNREF(grpc_mdelem_create(k, v, nullptr));
111 }
112
113 grpc_slice_unref(k);
114 grpc_slice_unref(v);
115 track_counters.Finish(state);
116 }
117 BENCHMARK(BM_MetadataFromInternedSlices);
118
BM_MetadataFromInternedSlicesAlreadyInIndex(benchmark::State & state)119 static void BM_MetadataFromInternedSlicesAlreadyInIndex(
120 benchmark::State& state) {
121 TrackCounters track_counters;
122 grpc_core::ManagedMemorySlice k("key");
123 grpc_core::ManagedMemorySlice v("value");
124 grpc_core::ExecCtx exec_ctx;
125 grpc_mdelem seed = grpc_mdelem_create(k, v, nullptr);
126 for (auto _ : state) {
127 GRPC_MDELEM_UNREF(grpc_mdelem_create(k, v, nullptr));
128 }
129 GRPC_MDELEM_UNREF(seed);
130
131 grpc_slice_unref(k);
132 grpc_slice_unref(v);
133 track_counters.Finish(state);
134 }
135 BENCHMARK(BM_MetadataFromInternedSlicesAlreadyInIndex);
136
BM_MetadataFromInternedKey(benchmark::State & state)137 static void BM_MetadataFromInternedKey(benchmark::State& state) {
138 TrackCounters track_counters;
139 grpc_core::ManagedMemorySlice k("key");
140 grpc_core::ExternallyManagedSlice v("value");
141 grpc_core::ExecCtx exec_ctx;
142 for (auto _ : state) {
143 GRPC_MDELEM_UNREF(grpc_mdelem_create(k, v, nullptr));
144 }
145
146 grpc_slice_unref(k);
147 track_counters.Finish(state);
148 }
149 BENCHMARK(BM_MetadataFromInternedKey);
150
BM_MetadataFromNonInternedSlicesWithBackingStore(benchmark::State & state)151 static void BM_MetadataFromNonInternedSlicesWithBackingStore(
152 benchmark::State& state) {
153 TrackCounters track_counters;
154 grpc_core::ExternallyManagedSlice k("key");
155 grpc_core::ExternallyManagedSlice v("value");
156 char backing_store[sizeof(grpc_mdelem_data)];
157 grpc_core::ExecCtx exec_ctx;
158 for (auto _ : state) {
159 GRPC_MDELEM_UNREF(grpc_mdelem_create(
160 k, v, reinterpret_cast<grpc_mdelem_data*>(backing_store)));
161 }
162
163 track_counters.Finish(state);
164 }
165 BENCHMARK(BM_MetadataFromNonInternedSlicesWithBackingStore);
166
BM_MetadataFromInternedSlicesWithBackingStore(benchmark::State & state)167 static void BM_MetadataFromInternedSlicesWithBackingStore(
168 benchmark::State& state) {
169 TrackCounters track_counters;
170 grpc_core::ManagedMemorySlice k("key");
171 grpc_core::ManagedMemorySlice v("value");
172 char backing_store[sizeof(grpc_mdelem_data)];
173 grpc_core::ExecCtx exec_ctx;
174 for (auto _ : state) {
175 GRPC_MDELEM_UNREF(grpc_mdelem_create(
176 k, v, reinterpret_cast<grpc_mdelem_data*>(backing_store)));
177 }
178
179 grpc_slice_unref(k);
180 grpc_slice_unref(v);
181 track_counters.Finish(state);
182 }
183 BENCHMARK(BM_MetadataFromInternedSlicesWithBackingStore);
184
BM_MetadataFromInternedKeyWithBackingStore(benchmark::State & state)185 static void BM_MetadataFromInternedKeyWithBackingStore(
186 benchmark::State& state) {
187 TrackCounters track_counters;
188 grpc_core::ManagedMemorySlice k("key");
189 grpc_core::ExternallyManagedSlice v("value");
190 char backing_store[sizeof(grpc_mdelem_data)];
191 grpc_core::ExecCtx exec_ctx;
192 for (auto _ : state) {
193 GRPC_MDELEM_UNREF(grpc_mdelem_create(
194 k, v, reinterpret_cast<grpc_mdelem_data*>(backing_store)));
195 }
196
197 grpc_slice_unref(k);
198 track_counters.Finish(state);
199 }
200 BENCHMARK(BM_MetadataFromInternedKeyWithBackingStore);
201
BM_MetadataFromStaticMetadataStrings(benchmark::State & state)202 static void BM_MetadataFromStaticMetadataStrings(benchmark::State& state) {
203 TrackCounters track_counters;
204 grpc_core::ExecCtx exec_ctx;
205 for (auto _ : state) {
206 GRPC_MDELEM_UNREF(
207 grpc_mdelem_create(GRPC_MDSTR_STATUS, GRPC_MDSTR_200, nullptr));
208 }
209
210 track_counters.Finish(state);
211 }
212 BENCHMARK(BM_MetadataFromStaticMetadataStrings);
213
BM_MetadataFromStaticMetadataStringsNotIndexed(benchmark::State & state)214 static void BM_MetadataFromStaticMetadataStringsNotIndexed(
215 benchmark::State& state) {
216 TrackCounters track_counters;
217 grpc_core::ExecCtx exec_ctx;
218 for (auto _ : state) {
219 GRPC_MDELEM_UNREF(
220 grpc_mdelem_create(GRPC_MDSTR_STATUS, GRPC_MDSTR_GZIP, nullptr));
221 }
222
223 track_counters.Finish(state);
224 }
225 BENCHMARK(BM_MetadataFromStaticMetadataStringsNotIndexed);
226
BM_MetadataRefUnrefExternal(benchmark::State & state)227 static void BM_MetadataRefUnrefExternal(benchmark::State& state) {
228 TrackCounters track_counters;
229 char backing_store[sizeof(grpc_mdelem_data)];
230 grpc_core::ExecCtx exec_ctx;
231 grpc_mdelem el =
232 grpc_mdelem_create(grpc_core::ExternallyManagedSlice("a"),
233 grpc_core::ExternallyManagedSlice("b"),
234 reinterpret_cast<grpc_mdelem_data*>(backing_store));
235 for (auto _ : state) {
236 GRPC_MDELEM_UNREF(GRPC_MDELEM_REF(el));
237 }
238 GRPC_MDELEM_UNREF(el);
239
240 track_counters.Finish(state);
241 }
242 BENCHMARK(BM_MetadataRefUnrefExternal);
243
BM_MetadataRefUnrefInterned(benchmark::State & state)244 static void BM_MetadataRefUnrefInterned(benchmark::State& state) {
245 TrackCounters track_counters;
246 char backing_store[sizeof(grpc_mdelem_data)];
247 grpc_core::ExecCtx exec_ctx;
248 grpc_core::ManagedMemorySlice k("key");
249 grpc_core::ManagedMemorySlice v("value");
250 grpc_mdelem el = grpc_mdelem_create(
251 k, v, reinterpret_cast<grpc_mdelem_data*>(backing_store));
252 grpc_slice_unref(k);
253 grpc_slice_unref(v);
254 for (auto _ : state) {
255 GRPC_MDELEM_UNREF(GRPC_MDELEM_REF(el));
256 }
257 GRPC_MDELEM_UNREF(el);
258
259 track_counters.Finish(state);
260 }
261 BENCHMARK(BM_MetadataRefUnrefInterned);
262
BM_MetadataRefUnrefAllocated(benchmark::State & state)263 static void BM_MetadataRefUnrefAllocated(benchmark::State& state) {
264 TrackCounters track_counters;
265 grpc_core::ExecCtx exec_ctx;
266 grpc_mdelem el =
267 grpc_mdelem_create(grpc_core::ExternallyManagedSlice("a"),
268 grpc_core::ExternallyManagedSlice("b"), nullptr);
269 for (auto _ : state) {
270 GRPC_MDELEM_UNREF(GRPC_MDELEM_REF(el));
271 }
272 GRPC_MDELEM_UNREF(el);
273
274 track_counters.Finish(state);
275 }
276 BENCHMARK(BM_MetadataRefUnrefAllocated);
277
BM_MetadataRefUnrefStatic(benchmark::State & state)278 static void BM_MetadataRefUnrefStatic(benchmark::State& state) {
279 TrackCounters track_counters;
280 grpc_core::ExecCtx exec_ctx;
281 grpc_mdelem el =
282 grpc_mdelem_create(GRPC_MDSTR_STATUS, GRPC_MDSTR_200, nullptr);
283 for (auto _ : state) {
284 GRPC_MDELEM_UNREF(GRPC_MDELEM_REF(el));
285 }
286 GRPC_MDELEM_UNREF(el);
287
288 track_counters.Finish(state);
289 }
290 BENCHMARK(BM_MetadataRefUnrefStatic);
291
292 // Some distros have RunSpecifiedBenchmarks under the benchmark namespace,
293 // and others do not. This allows us to support both modes.
294 namespace benchmark {
RunTheBenchmarksNamespaced()295 void RunTheBenchmarksNamespaced() { RunSpecifiedBenchmarks(); }
296 } // namespace benchmark
297
main(int argc,char ** argv)298 int main(int argc, char** argv) {
299 grpc::testing::TestEnvironment env(argc, argv);
300 LibraryInitializer libInit;
301 ::benchmark::Initialize(&argc, argv);
302 ::grpc::testing::InitTest(&argc, &argv, false);
303 benchmark::RunTheBenchmarksNamespaced();
304 return 0;
305 }
306