Home | History | Annotate | Download | only in microbenchmarks
      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