Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions exporters/otlp/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -1040,6 +1040,7 @@ otel_cc_benchmark(
"//sdk/src/metrics",
"//sdk/src/resource",
"//sdk/src/trace",
"//test_common:headers",
"@com_github_opentelemetry_proto//:trace_service_proto_cc",
],
)
8 changes: 6 additions & 2 deletions exporters/otlp/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1225,7 +1225,11 @@ if(WITH_BENCHMARK)

target_link_libraries(
otlp_recordable_benchmark
PRIVATE opentelemetry_otlp_recordable opentelemetry_trace
opentelemetry_metrics opentelemetry_resources benchmark::benchmark
PRIVATE opentelemetry_otlp_recordable
opentelemetry_trace
opentelemetry_metrics
opentelemetry_resources
benchmark::benchmark
opentelemetry_test_common
${CMAKE_THREAD_LIBS_INIT})
endif()
323 changes: 154 additions & 169 deletions exporters/otlp/test/otlp_recordable_benchmark.cc

Large diffs are not rendered by default.

6 changes: 2 additions & 4 deletions sdk/src/trace/span_data.cc
Original file line number Diff line number Diff line change
Expand Up @@ -100,15 +100,13 @@ void SpanData::AddEvent(nostd::string_view name,
opentelemetry::common::SystemTimestamp timestamp,
const opentelemetry::common::KeyValueIterable &attributes) noexcept
{
SpanDataEvent event(std::string(name), timestamp, attributes);
events_.push_back(event);
events_.emplace_back(std::string(name), timestamp, attributes);
}

void SpanData::AddLink(const opentelemetry::trace::SpanContext &span_context,
const opentelemetry::common::KeyValueIterable &attributes) noexcept
{
SpanDataLink link(span_context, attributes);
links_.push_back(link);
links_.emplace_back(span_context, attributes);
}

void SpanData::SetStatus(opentelemetry::trace::StatusCode code,
Expand Down
16 changes: 16 additions & 0 deletions sdk/test/trace/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -205,3 +205,19 @@ otel_cc_benchmark(
"//sdk/src/trace",
],
)

otel_cc_benchmark(
name = "span_data_benchmark",
srcs = ["span_data_benchmark.cc"],
tags = [
"benchmark",
"test",
"trace",
],
deps = [
"//exporters/memory:in_memory_span_exporter",
"//sdk/src/resource",
"//sdk/src/trace",
"//test_common:headers",
],
)
10 changes: 10 additions & 0 deletions sdk/test/trace/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,14 @@ if(WITH_BENCHMARK)
sampler_benchmark benchmark::benchmark ${CMAKE_THREAD_LIBS_INIT}
opentelemetry_trace opentelemetry_resources
opentelemetry_exporter_in_memory)

add_executable(span_data_benchmark span_data_benchmark.cc)
target_link_libraries(
span_data_benchmark
benchmark::benchmark
${CMAKE_THREAD_LIBS_INIT}
opentelemetry_trace
opentelemetry_resources
opentelemetry_exporter_in_memory
opentelemetry_test_common)
endif()
213 changes: 213 additions & 0 deletions sdk/test/trace/span_data_benchmark.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,213 @@
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0

// clang-format off
//
// ~/build/sdk/test/trace/span_data_benchmark --benchmark_repetitions=5 --benchmark_display_aggregates_only=true
// 2026-07-01T15:59:10+00:00
// Running /home/devuser/build/sdk/test/trace/span_data_benchmark
// Run on (32 X 5700 MHz CPU s)
// CPU Caches:
// L1 Data 48 KiB (x16)
// L1 Instruction 32 KiB (x16)
// L2 Unified 2048 KiB (x16)
// L3 Unified 36864 KiB (x1)
// Load Average: 1.35, 1.52, 1.62
// ***WARNING*** ASLR is enabled, the results may have unreproducible noise in them.
// --------------------------------------------------------------------------------------------------------------
// Benchmark Time CPU Iterations
// --------------------------------------------------------------------------------------------------------------
// SpanDataFixture/RecordMinimalSpan_mean 341 ns 343 ns 5
// SpanDataFixture/RecordMinimalSpan_median 341 ns 343 ns 5
// SpanDataFixture/RecordMinimalSpan_stddev 0.950 ns 0.988 ns 5
// SpanDataFixture/RecordMinimalSpan_cv 0.28 % 0.29 % 5
// SpanDataFixture/RecordNominalSpan_mean 581 ns 584 ns 5
// SpanDataFixture/RecordNominalSpan_median 588 ns 590 ns 5
// SpanDataFixture/RecordNominalSpan_stddev 15.3 ns 15.1 ns 5
// SpanDataFixture/RecordNominalSpan_cv 2.63 % 2.59 % 5
// SpanDataFixture/RecordSpanWithAttributes/attribute_count:1_mean 390 ns 394 ns 5 items_per_second=2.5415M/s
// SpanDataFixture/RecordSpanWithAttributes/attribute_count:1_median 391 ns 395 ns 5 items_per_second=2.53367M/s
// SpanDataFixture/RecordSpanWithAttributes/attribute_count:1_stddev 4.17 ns 4.40 ns 5 items_per_second=28.4487k/s
// SpanDataFixture/RecordSpanWithAttributes/attribute_count:1_cv 1.07 % 1.12 % 5 items_per_second=1.12%
// SpanDataFixture/RecordSpanWithAttributes/attribute_count:10_mean 705 ns 708 ns 5 items_per_second=14.1257M/s
// SpanDataFixture/RecordSpanWithAttributes/attribute_count:10_median 707 ns 711 ns 5 items_per_second=14.0739M/s
// SpanDataFixture/RecordSpanWithAttributes/attribute_count:10_stddev 6.35 ns 6.36 ns 5 items_per_second=127.942k/s
// SpanDataFixture/RecordSpanWithAttributes/attribute_count:10_cv 0.90 % 0.90 % 5 items_per_second=0.91%
// SpanDataFixture/RecordSpanWithAttributes/attribute_count:128_mean 7479 ns 7484 ns 5 items_per_second=17.1122M/s
// SpanDataFixture/RecordSpanWithAttributes/attribute_count:128_median 7539 ns 7543 ns 5 items_per_second=16.969M/s
// SpanDataFixture/RecordSpanWithAttributes/attribute_count:128_stddev 189 ns 189 ns 5 items_per_second=438.424k/s
// SpanDataFixture/RecordSpanWithAttributes/attribute_count:128_cv 2.53 % 2.53 % 5 items_per_second=2.56%
// SpanDataFixture/RecordSpanWithEvents/event_count:1_mean 456 ns 459 ns 5 items_per_second=2.17751M/s
// SpanDataFixture/RecordSpanWithEvents/event_count:1_median 456 ns 459 ns 5 items_per_second=2.178M/s
// SpanDataFixture/RecordSpanWithEvents/event_count:1_stddev 2.89 ns 3.02 ns 5 items_per_second=14.3182k/s
// SpanDataFixture/RecordSpanWithEvents/event_count:1_cv 0.63 % 0.66 % 5 items_per_second=0.66%
// SpanDataFixture/RecordSpanWithEvents/event_count:10_mean 1584 ns 1587 ns 5 items_per_second=6.30345M/s
// SpanDataFixture/RecordSpanWithEvents/event_count:10_median 1580 ns 1583 ns 5 items_per_second=6.318M/s
// SpanDataFixture/RecordSpanWithEvents/event_count:10_stddev 24.3 ns 24.4 ns 5 items_per_second=95.4207k/s
// SpanDataFixture/RecordSpanWithEvents/event_count:10_cv 1.54 % 1.54 % 5 items_per_second=1.51%
// SpanDataFixture/RecordSpanWithEvents/event_count:128_mean 16434 ns 16438 ns 5 items_per_second=7.78791M/s
// SpanDataFixture/RecordSpanWithEvents/event_count:128_median 16429 ns 16432 ns 5 items_per_second=7.78954M/s
// SpanDataFixture/RecordSpanWithEvents/event_count:128_stddev 211 ns 211 ns 5 items_per_second=100.089k/s
// SpanDataFixture/RecordSpanWithEvents/event_count:128_cv 1.28 % 1.28 % 5 items_per_second=1.29%
// SpanDataFixture/RecordSpanWithLinks/link_count:1_mean 435 ns 437 ns 5 items_per_second=2.29077M/s
// SpanDataFixture/RecordSpanWithLinks/link_count:1_median 435 ns 436 ns 5 items_per_second=2.29368M/s
// SpanDataFixture/RecordSpanWithLinks/link_count:1_stddev 2.12 ns 2.39 ns 5 items_per_second=12.5108k/s
// SpanDataFixture/RecordSpanWithLinks/link_count:1_cv 0.49 % 0.55 % 5 items_per_second=0.55%
// SpanDataFixture/RecordSpanWithLinks/link_count:10_mean 1368 ns 1371 ns 5 items_per_second=7.2967M/s
// SpanDataFixture/RecordSpanWithLinks/link_count:10_median 1375 ns 1378 ns 5 items_per_second=7.25823M/s
// SpanDataFixture/RecordSpanWithLinks/link_count:10_stddev 22.3 ns 22.4 ns 5 items_per_second=121.346k/s
// SpanDataFixture/RecordSpanWithLinks/link_count:10_cv 1.63 % 1.63 % 5 items_per_second=1.66%
// SpanDataFixture/RecordSpanWithLinks/link_count:128_mean 15304 ns 15308 ns 5 items_per_second=8.38477M/s
// SpanDataFixture/RecordSpanWithLinks/link_count:128_median 14933 ns 14937 ns 5 items_per_second=8.56932M/s
// SpanDataFixture/RecordSpanWithLinks/link_count:128_stddev 930 ns 930 ns 5 items_per_second=474.386k/s
// SpanDataFixture/RecordSpanWithLinks/link_count:128_cv 6.08 % 6.08 % 5 items_per_second=5.66%
//
// clang-format on

#include <benchmark/benchmark.h>

#include <cstddef>
#include <cstdint>
#include <string>
#include <utility>
#include <vector>

#include "opentelemetry/exporters/memory/in_memory_span_exporter.h"
#include "opentelemetry/nostd/shared_ptr.h"
#include "opentelemetry/nostd/string_view.h"
#include "opentelemetry/sdk/instrumentationscope/instrumentation_scope.h"
#include "opentelemetry/sdk/trace/tracer_provider.h"
#include "opentelemetry/test_common/sdk/trace/test_utils.h"
#include "opentelemetry/trace/span.h"
#include "opentelemetry/trace/tracer.h"

namespace trace_sdk = opentelemetry::sdk::trace;
namespace test_utils = opentelemetry::test_common;

namespace
{

class SpanDataFixture : public benchmark::Fixture
{
public:
using benchmark::Fixture::SetUp;

void SetUp(benchmark::State &) override
{
auto exporter = std::make_unique<opentelemetry::exporter::memory::InMemorySpanExporter>();
auto processor = std::make_unique<test_utils::BufferingSpanProcessor>(std::move(exporter));
provider_ = std::make_shared<trace_sdk::TracerProvider>(std::move(processor));
tracer_ = provider_->GetTracer(test_utils::TestScope().GetName(),
test_utils::TestScope().GetVersion(),
test_utils::TestScope().GetSchemaURL());
test_utils::InitializeSpanTestData();
}

protected:
std::shared_ptr<trace_sdk::TracerProvider> provider_;
opentelemetry::nostd::shared_ptr<opentelemetry::trace::Tracer> tracer_;
};

} // namespace

// Baseline: start a span and end it immediately with no attributes, links, or events.
BENCHMARK_DEFINE_F(SpanDataFixture, RecordMinimalSpan)(benchmark::State &state)
{
for (auto _ : state)
{
auto span = test_utils::StartMinimalSpan(*tracer_);
span->End();
state.PauseTiming();
provider_->ForceFlush();
state.ResumeTiming();
}
}
BENCHMARK_REGISTER_F(SpanDataFixture, RecordMinimalSpan)->Unit(benchmark::kNanosecond);

// RecordNominalSpan span: representative mix of attribute types passed at creation.
BENCHMARK_DEFINE_F(SpanDataFixture, RecordNominalSpan)(benchmark::State &state)
{
for (auto _ : state)
{
auto span = test_utils::StartNominalSpan(*tracer_);
span->End();
state.PauseTiming();
provider_->ForceFlush();
state.ResumeTiming();
}
}
BENCHMARK_REGISTER_F(SpanDataFixture, RecordNominalSpan)->Unit(benchmark::kNanosecond);

BENCHMARK_DEFINE_F(SpanDataFixture, RecordSpanWithAttributes)(benchmark::State &state)
{
const int64_t attribute_count = state.range(0);
const std::vector<test_utils::SpanAttribute> attributes =
test_utils::MakeAttributes(attribute_count);
for (auto _ : state)
{
auto span = test_utils::StartSpanWithAttributes(*tracer_, attributes);
span->End();
state.PauseTiming();
provider_->ForceFlush();
state.ResumeTiming();
}
state.SetItemsProcessed(state.iterations() * attribute_count);
}
BENCHMARK_REGISTER_F(SpanDataFixture, RecordSpanWithAttributes)
->ArgName("attribute_count")
->Arg(1)
->Arg(10)
->Arg(test_utils::kSpanAttributeLimit)
->Unit(benchmark::kNanosecond);

BENCHMARK_DEFINE_F(SpanDataFixture, RecordSpanWithEvents)(benchmark::State &state)
{
const int64_t event_count = state.range(0);

for (auto _ : state)
{
auto span = test_utils::StartSpanWithEvents(*tracer_, static_cast<std::size_t>(event_count));
span->End();
state.PauseTiming();
provider_->ForceFlush();
state.ResumeTiming();
}
state.SetItemsProcessed(state.iterations() * event_count);
}
BENCHMARK_REGISTER_F(SpanDataFixture, RecordSpanWithEvents)
->ArgName("event_count")
->Arg(1)
->Arg(10)
->Arg(test_utils::kSpanEventLimit)
->Unit(benchmark::kNanosecond);

BENCHMARK_DEFINE_F(SpanDataFixture, RecordSpanWithLinks)(benchmark::State &state)
{
const int64_t link_count = state.range(0);
const std::vector<test_utils::LinkEntry> link_entries =
test_utils::MakeLinkEntries(static_cast<std::size_t>(link_count));

for (auto _ : state)
{
auto span = test_utils::StartSpanWithLinks(*tracer_, link_entries);
span->End();
state.PauseTiming();
provider_->ForceFlush();
state.ResumeTiming();
}
state.SetItemsProcessed(state.iterations() * link_count);
}
BENCHMARK_REGISTER_F(SpanDataFixture, RecordSpanWithLinks)
->ArgName("link_count")
->Arg(1)
->Arg(10)
->Arg(test_utils::kSpanLinkLimit)
->Unit(benchmark::kNanosecond);

int main(int argc, char **argv)
{
benchmark::Initialize(&argc, argv);
benchmark::RunSpecifiedBenchmarks();
benchmark::Shutdown();
return 0;
}
Loading
Loading