123 lines
3.4 KiB
Rust
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);
|