| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181 | // Copyright The OpenTelemetry Authors// SPDX-License-Identifier: Apache-2.0#include <benchmark/benchmark.h>#include <algorithm>#include <map>#include <string>#include <utility>#include <vector>#include "opentelemetry/common/key_value_iterable_view.h"#include "opentelemetry/context/context_value.h"  // IWYU pragma: keep#include "opentelemetry/exporters/memory/in_memory_span_exporter.h"#include "opentelemetry/nostd/shared_ptr.h"#include "opentelemetry/sdk/resource/resource.h"#include "opentelemetry/sdk/trace/exporter.h"#include "opentelemetry/sdk/trace/processor.h"#include "opentelemetry/sdk/trace/sampler.h"#include "opentelemetry/sdk/trace/samplers/always_off.h"#include "opentelemetry/sdk/trace/samplers/always_on.h"#include "opentelemetry/sdk/trace/samplers/parent.h"#include "opentelemetry/sdk/trace/samplers/trace_id_ratio.h"#include "opentelemetry/sdk/trace/simple_processor.h"#include "opentelemetry/sdk/trace/tracer.h"#include "opentelemetry/sdk/trace/tracer_context.h"#include "opentelemetry/trace/span.h"#include "opentelemetry/trace/span_context.h"#include "opentelemetry/trace/span_context_kv_iterable_view.h"#include "opentelemetry/trace/span_metadata.h"#include "opentelemetry/trace/trace_id.h"#include "opentelemetry/trace/tracer.h"using namespace opentelemetry::sdk::trace;using opentelemetry::exporter::memory::InMemorySpanExporter;using opentelemetry::trace::SpanContext;namespace{// Sampler constructor used as a baseline to compare with other samplersvoid BM_AlwaysOffSamplerConstruction(benchmark::State &state){  while (state.KeepRunning())  {    benchmark::DoNotOptimize(AlwaysOffSampler());  }}BENCHMARK(BM_AlwaysOffSamplerConstruction);// Sampler constructor used as a baseline to compare with other samplersvoid BM_AlwaysOnSamplerConstruction(benchmark::State &state){  while (state.KeepRunning())  {    benchmark::DoNotOptimize(AlwaysOnSampler());  }}BENCHMARK(BM_AlwaysOnSamplerConstruction);/*  Fails to build with GCC.  See upstream bug: https://github.com/google/benchmark/issues/1675*/#if 0void BM_ParentBasedSamplerConstruction(benchmark::State &state){  while (state.KeepRunning())  {    benchmark::DoNotOptimize(ParentBasedSampler(std::make_shared<AlwaysOnSampler>()));  }}BENCHMARK(BM_ParentBasedSamplerConstruction);void BM_TraceIdRatioBasedSamplerConstruction(benchmark::State &state){  while (state.KeepRunning())  {    benchmark::DoNotOptimize(TraceIdRatioBasedSampler(0.01));  }}BENCHMARK(BM_TraceIdRatioBasedSamplerConstruction);#endif// Sampler Helper Functionvoid BenchmarkShouldSampler(Sampler &sampler, benchmark::State &state){  opentelemetry::trace::TraceId trace_id;  opentelemetry::trace::SpanKind span_kind = opentelemetry::trace::SpanKind::kInternal;  using M = std::map<std::string, int>;  M m1    = {{}};  using L =      std::vector<std::pair<opentelemetry::trace::SpanContext, std::map<std::string, std::string>>>;  L l1 = {{opentelemetry::trace::SpanContext(false, false), {}},          {opentelemetry::trace::SpanContext(false, false), {}}};  opentelemetry::common::KeyValueIterableView<M> view{m1};  opentelemetry::trace::SpanContextKeyValueIterableView<L> links{l1};  while (state.KeepRunning())  {    auto invalid_ctx = SpanContext::GetInvalid();    benchmark::DoNotOptimize(        sampler.ShouldSample(invalid_ctx, trace_id, "", span_kind, view, links));  }}// Sampler used as a baseline to compare with other samplersvoid BM_AlwaysOffSamplerShouldSample(benchmark::State &state){  AlwaysOffSampler sampler;  BenchmarkShouldSampler(sampler, state);}BENCHMARK(BM_AlwaysOffSamplerShouldSample);// Sampler used as a baseline to compare with other samplersvoid BM_AlwaysOnSamplerShouldSample(benchmark::State &state){  AlwaysOnSampler sampler;  BenchmarkShouldSampler(sampler, state);}BENCHMARK(BM_AlwaysOnSamplerShouldSample);void BM_ParentBasedSamplerShouldSample(benchmark::State &state){  ParentBasedSampler sampler(std::make_shared<AlwaysOnSampler>());  BenchmarkShouldSampler(sampler, state);}BENCHMARK(BM_ParentBasedSamplerShouldSample);void BM_TraceIdRatioBasedSamplerShouldSample(benchmark::State &state){  TraceIdRatioBasedSampler sampler(0.01);  BenchmarkShouldSampler(sampler, state);}BENCHMARK(BM_TraceIdRatioBasedSamplerShouldSample);// Sampler Helper Functionvoid BenchmarkSpanCreation(std::unique_ptr<Sampler> &&sampler, benchmark::State &state){  std::unique_ptr<SpanExporter> exporter(new InMemorySpanExporter());  std::unique_ptr<SpanProcessor> processor(new SimpleSpanProcessor(std::move(exporter)));  std::vector<std::unique_ptr<SpanProcessor>> processors;  processors.push_back(std::move(processor));  auto resource = opentelemetry::sdk::resource::Resource::Create({});  auto context =      std::make_shared<TracerContext>(std::move(processors), resource, std::move(sampler));  auto tracer = std::shared_ptr<opentelemetry::trace::Tracer>(new Tracer(context));  while (state.KeepRunning())  {    auto span = tracer->StartSpan("span");    span->SetAttribute("attr1", 3.1);    span->End();  }}// Test to measure performance for span creationvoid BM_SpanCreation(benchmark::State &state){  std::unique_ptr<Sampler> sampler(new AlwaysOnSampler());  BenchmarkSpanCreation(std::move(sampler), state);}BENCHMARK(BM_SpanCreation);// Test to measure performance overhead for no-op span creationvoid BM_NoopSpanCreation(benchmark::State &state){  std::unique_ptr<Sampler> sampler(new AlwaysOffSampler());  BenchmarkSpanCreation(std::move(sampler), state);}BENCHMARK(BM_NoopSpanCreation);}  // namespaceBENCHMARK_MAIN();
 |