sampler_benchmark.cc 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. // Copyright The OpenTelemetry Authors
  2. // SPDX-License-Identifier: Apache-2.0
  3. #include <benchmark/benchmark.h>
  4. #include <algorithm>
  5. #include <map>
  6. #include <string>
  7. #include <utility>
  8. #include <vector>
  9. #include "opentelemetry/common/key_value_iterable_view.h"
  10. #include "opentelemetry/context/context_value.h" // IWYU pragma: keep
  11. #include "opentelemetry/exporters/memory/in_memory_span_exporter.h"
  12. #include "opentelemetry/nostd/shared_ptr.h"
  13. #include "opentelemetry/sdk/resource/resource.h"
  14. #include "opentelemetry/sdk/trace/exporter.h"
  15. #include "opentelemetry/sdk/trace/processor.h"
  16. #include "opentelemetry/sdk/trace/sampler.h"
  17. #include "opentelemetry/sdk/trace/samplers/always_off.h"
  18. #include "opentelemetry/sdk/trace/samplers/always_on.h"
  19. #include "opentelemetry/sdk/trace/samplers/parent.h"
  20. #include "opentelemetry/sdk/trace/samplers/trace_id_ratio.h"
  21. #include "opentelemetry/sdk/trace/simple_processor.h"
  22. #include "opentelemetry/sdk/trace/tracer.h"
  23. #include "opentelemetry/sdk/trace/tracer_context.h"
  24. #include "opentelemetry/trace/span.h"
  25. #include "opentelemetry/trace/span_context.h"
  26. #include "opentelemetry/trace/span_context_kv_iterable_view.h"
  27. #include "opentelemetry/trace/span_metadata.h"
  28. #include "opentelemetry/trace/trace_id.h"
  29. #include "opentelemetry/trace/tracer.h"
  30. using namespace opentelemetry::sdk::trace;
  31. using opentelemetry::exporter::memory::InMemorySpanExporter;
  32. using opentelemetry::trace::SpanContext;
  33. namespace
  34. {
  35. // Sampler constructor used as a baseline to compare with other samplers
  36. void BM_AlwaysOffSamplerConstruction(benchmark::State &state)
  37. {
  38. while (state.KeepRunning())
  39. {
  40. benchmark::DoNotOptimize(AlwaysOffSampler());
  41. }
  42. }
  43. BENCHMARK(BM_AlwaysOffSamplerConstruction);
  44. // Sampler constructor used as a baseline to compare with other samplers
  45. void BM_AlwaysOnSamplerConstruction(benchmark::State &state)
  46. {
  47. while (state.KeepRunning())
  48. {
  49. benchmark::DoNotOptimize(AlwaysOnSampler());
  50. }
  51. }
  52. BENCHMARK(BM_AlwaysOnSamplerConstruction);
  53. /*
  54. Fails to build with GCC.
  55. See upstream bug: https://github.com/google/benchmark/issues/1675
  56. */
  57. #if 0
  58. void BM_ParentBasedSamplerConstruction(benchmark::State &state)
  59. {
  60. while (state.KeepRunning())
  61. {
  62. benchmark::DoNotOptimize(ParentBasedSampler(std::make_shared<AlwaysOnSampler>()));
  63. }
  64. }
  65. BENCHMARK(BM_ParentBasedSamplerConstruction);
  66. void BM_TraceIdRatioBasedSamplerConstruction(benchmark::State &state)
  67. {
  68. while (state.KeepRunning())
  69. {
  70. benchmark::DoNotOptimize(TraceIdRatioBasedSampler(0.01));
  71. }
  72. }
  73. BENCHMARK(BM_TraceIdRatioBasedSamplerConstruction);
  74. #endif
  75. // Sampler Helper Function
  76. void BenchmarkShouldSampler(Sampler &sampler, benchmark::State &state)
  77. {
  78. opentelemetry::trace::TraceId trace_id;
  79. opentelemetry::trace::SpanKind span_kind = opentelemetry::trace::SpanKind::kInternal;
  80. using M = std::map<std::string, int>;
  81. M m1 = {{}};
  82. using L =
  83. std::vector<std::pair<opentelemetry::trace::SpanContext, std::map<std::string, std::string>>>;
  84. L l1 = {{opentelemetry::trace::SpanContext(false, false), {}},
  85. {opentelemetry::trace::SpanContext(false, false), {}}};
  86. opentelemetry::common::KeyValueIterableView<M> view{m1};
  87. opentelemetry::trace::SpanContextKeyValueIterableView<L> links{l1};
  88. while (state.KeepRunning())
  89. {
  90. auto invalid_ctx = SpanContext::GetInvalid();
  91. benchmark::DoNotOptimize(
  92. sampler.ShouldSample(invalid_ctx, trace_id, "", span_kind, view, links));
  93. }
  94. }
  95. // Sampler used as a baseline to compare with other samplers
  96. void BM_AlwaysOffSamplerShouldSample(benchmark::State &state)
  97. {
  98. AlwaysOffSampler sampler;
  99. BenchmarkShouldSampler(sampler, state);
  100. }
  101. BENCHMARK(BM_AlwaysOffSamplerShouldSample);
  102. // Sampler used as a baseline to compare with other samplers
  103. void BM_AlwaysOnSamplerShouldSample(benchmark::State &state)
  104. {
  105. AlwaysOnSampler sampler;
  106. BenchmarkShouldSampler(sampler, state);
  107. }
  108. BENCHMARK(BM_AlwaysOnSamplerShouldSample);
  109. void BM_ParentBasedSamplerShouldSample(benchmark::State &state)
  110. {
  111. ParentBasedSampler sampler(std::make_shared<AlwaysOnSampler>());
  112. BenchmarkShouldSampler(sampler, state);
  113. }
  114. BENCHMARK(BM_ParentBasedSamplerShouldSample);
  115. void BM_TraceIdRatioBasedSamplerShouldSample(benchmark::State &state)
  116. {
  117. TraceIdRatioBasedSampler sampler(0.01);
  118. BenchmarkShouldSampler(sampler, state);
  119. }
  120. BENCHMARK(BM_TraceIdRatioBasedSamplerShouldSample);
  121. // Sampler Helper Function
  122. void BenchmarkSpanCreation(std::unique_ptr<Sampler> &&sampler, benchmark::State &state)
  123. {
  124. std::unique_ptr<SpanExporter> exporter(new InMemorySpanExporter());
  125. std::unique_ptr<SpanProcessor> processor(new SimpleSpanProcessor(std::move(exporter)));
  126. std::vector<std::unique_ptr<SpanProcessor>> processors;
  127. processors.push_back(std::move(processor));
  128. auto resource = opentelemetry::sdk::resource::Resource::Create({});
  129. auto context =
  130. std::make_shared<TracerContext>(std::move(processors), resource, std::move(sampler));
  131. auto tracer = std::shared_ptr<opentelemetry::trace::Tracer>(new Tracer(context));
  132. while (state.KeepRunning())
  133. {
  134. auto span = tracer->StartSpan("span");
  135. span->SetAttribute("attr1", 3.1);
  136. span->End();
  137. }
  138. }
  139. // Test to measure performance for span creation
  140. void BM_SpanCreation(benchmark::State &state)
  141. {
  142. std::unique_ptr<Sampler> sampler(new AlwaysOnSampler());
  143. BenchmarkSpanCreation(std::move(sampler), state);
  144. }
  145. BENCHMARK(BM_SpanCreation);
  146. // Test to measure performance overhead for no-op span creation
  147. void BM_NoopSpanCreation(benchmark::State &state)
  148. {
  149. std::unique_ptr<Sampler> sampler(new AlwaysOffSampler());
  150. BenchmarkSpanCreation(std::move(sampler), state);
  151. }
  152. BENCHMARK(BM_NoopSpanCreation);
  153. } // namespace
  154. BENCHMARK_MAIN();