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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 { 297 void RunTheBenchmarksNamespaced() { RunSpecifiedBenchmarks(); } 298 } // namespace benchmark 299 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