Files
jcoffey-dev 1e7e8dfd48
ci / fork-checks (pull_request) Skipped
ci / build (pull_request) Skipped
github/ci (branch) GitHub Actions
ci / github (pull_request) Successful in 7m26s
Vendor upstream's opentelemetry-rust fork at the pinned commit
2026-10-27 22:55:35 -07:00

123 lines
3.4 KiB
Rust

use criterion::{
criterion_group, criterion_main, measurement::WallTime, BenchmarkGroup, BenchmarkId, Criterion,
};
use opentelemetry::{
trace::{SpanContext, TraceContextExt, TraceState},
Context, SpanId, TraceFlags, TraceId,
};
use std::hint::black_box;
// Run this benchmark with:
// cargo bench --bench context_attach
fn criterion_benchmark(c: &mut Criterion) {
let remote_context = SpanContext::new(
TraceId::from(47),
SpanId::from(11),
TraceFlags::SAMPLED,
true,
TraceState::NONE,
);
let span_context = Context::new().with_remote_span_context(remote_context);
let contexts = vec![
("empty_cx", Context::new()),
("single_value_cx", Context::new().with_value(Value(4711))),
("span_cx", span_context),
];
for (name, cx) in contexts {
single_cx_scope(&mut group(c), name, &cx);
nested_cx_scope(&mut group(c), name, &cx);
overlapping_cx_scope(&mut group(c), name, &cx);
}
}
fn single_cx_scope(
group: &mut BenchmarkGroup<'_, WallTime>,
context_type: &str,
context: &Context,
) {
group.bench_function(BenchmarkId::new("single_cx", context_type), |b| {
b.iter_batched(
|| context.clone(),
|cx| {
single_cx(cx);
},
criterion::BatchSize::SmallInput,
);
});
}
#[inline(never)]
fn single_cx(cx: Context) {
let _cx_guard = black_box(cx.attach());
let _ = black_box(dummy_work());
}
fn nested_cx_scope(group: &mut BenchmarkGroup<'_, WallTime>, cx_type: &str, context: &Context) {
group.bench_function(BenchmarkId::new("nested_cx", cx_type), |b| {
b.iter_batched(
|| (context.clone(), context.clone()),
|(cx1, cx2)| {
nested_cx(cx1, cx2);
},
criterion::BatchSize::SmallInput,
);
});
}
#[inline(never)]
fn nested_cx(cx1: Context, cx2: Context) {
let _outer_cx_guard = black_box(cx1.attach());
let _inner_cx_guard = black_box(cx2.attach());
let _ = black_box(dummy_work());
}
fn overlapping_cx_scope(
group: &mut BenchmarkGroup<'_, WallTime>,
cx_type: &str,
context: &Context,
) {
// This is to ensure that the context is restored after the benchmark,
// see https://github.com/open-telemetry/opentelemetry-rust/issues/1887
let _restore_cx_guard = Context::current().attach();
group.bench_function(BenchmarkId::new("out_of_order_cx_drop", cx_type), |b| {
b.iter_batched(
|| (context.clone(), context.clone()),
|(cx1, cx2)| {
out_of_order_cx_drop(cx1, cx2);
},
criterion::BatchSize::SmallInput,
);
});
}
#[inline(never)]
fn out_of_order_cx_drop(cx1: Context, cx2: Context) {
let outer_cx_guard = cx1.attach();
let inner_cx_guard = cx2.attach();
let _ = black_box(dummy_work());
drop(outer_cx_guard);
drop(inner_cx_guard);
}
#[inline(never)]
fn dummy_work() -> i32 {
black_box(1 + 1)
}
fn group(c: &mut Criterion) -> BenchmarkGroup<'_, WallTime> {
c.benchmark_group("context_attach")
}
#[derive(Debug, PartialEq)]
struct Value(i32);
criterion_group! {
name = benches;
config = Criterion::default()
.warm_up_time(std::time::Duration::from_secs(1))
.measurement_time(std::time::Duration::from_secs(2));
targets = criterion_benchmark
}
criterion_main!(benches);