Skip to content

Commit

Permalink
Merge branch 'main' into cijothomas/example-tracer-reuse
Browse files Browse the repository at this point in the history
  • Loading branch information
cijothomas authored Feb 26, 2025
2 parents 5d86c8b + 4830a3c commit f65ffb7
Show file tree
Hide file tree
Showing 5 changed files with 185 additions and 11 deletions.
28 changes: 28 additions & 0 deletions .github/workflows/pr_criterion.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
on: [pull_request]
name: benchmark pull requests
jobs:
runBenchmark:
name: run benchmark
permissions:
pull-requests: write
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: arduino/setup-protoc@v3
- uses: dtolnay/rust-toolchain@master
with:
toolchain: stable
- uses: boa-dev/criterion-compare-action@v3
with:
cwd: opentelemetry
branchName: ${{ github.base_ref }}
- uses: boa-dev/criterion-compare-action@v3
with:
cwd: opentelemetry-appender-tracing
features: spec_unstable_logs_enabled
branchName: ${{ github.base_ref }}
- uses: boa-dev/criterion-compare-action@v3
with:
cwd: opentelemetry-sdk
features: rt-tokio,testing,metrics,logs,spec_unstable_metrics_views
branchName: ${{ github.base_ref }}
49 changes: 39 additions & 10 deletions opentelemetry-sdk/benches/context.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion, Throughput};
use criterion::{black_box, criterion_group, criterion_main, BenchmarkId, Criterion};
use opentelemetry::{
global::BoxedTracer,
trace::{
Expand All @@ -17,7 +17,6 @@ use std::fmt::Display;

fn criterion_benchmark(c: &mut Criterion) {
let mut group = c.benchmark_group("context");
group.throughput(Throughput::Elements(1));
for env in [
Environment::InContext,
Environment::NoContext,
Expand All @@ -30,27 +29,57 @@ fn criterion_benchmark(c: &mut Criterion) {
group.bench_function(
BenchmarkId::new("has_active_span", param.clone()),
|b| match api {
Api::Alt => b.iter(|| Context::map_current(TraceContextExt::has_active_span)),
Api::Spec => b.iter(|| Context::current().has_active_span()),
Api::Alt => b.iter(has_active_span_alt),
Api::Spec => b.iter(has_active_span_spec),
},
);
group.bench_function(
BenchmarkId::new("is_sampled", param.clone()),
|b| match api {
Api::Alt => {
b.iter(|| Context::map_current(|cx| cx.span().span_context().is_sampled()))
}
Api::Spec => b.iter(|| Context::current().span().span_context().is_sampled()),
Api::Alt => b.iter(is_sampled_alt),
Api::Spec => b.iter(is_sampled_spec),
},
);
group.bench_function(BenchmarkId::new("is_recording", param), |b| match api {
Api::Alt => b.iter(|| Context::map_current(|cx| cx.span().is_recording())),
Api::Spec => b.iter(|| Context::current().span().is_recording()),
Api::Alt => b.iter(is_recording_alt),
Api::Spec => b.iter(is_recording_spec),
});
}
}
}

#[inline(never)]
fn has_active_span_alt() {
let _ = black_box(Context::map_current(TraceContextExt::has_active_span));
}

#[inline(never)]
fn has_active_span_spec() {
let _ = black_box(Context::current().has_active_span());
}

#[inline(never)]
fn is_sampled_alt() {
let _ = black_box(Context::map_current(|cx| {
cx.span().span_context().is_sampled()
}));
}

#[inline(never)]
fn is_sampled_spec() {
let _ = black_box(Context::current().span().span_context().is_sampled());
}

#[inline(never)]
fn is_recording_alt() {
let _ = black_box(Context::map_current(|cx| cx.span().is_recording()));
}

#[inline(never)]
fn is_recording_spec() {
let _ = black_box(Context::current().span().is_recording());
}

#[derive(Copy, Clone)]
enum Api {
/// An alternative way which may be faster than what the spec recommends.
Expand Down
4 changes: 3 additions & 1 deletion opentelemetry-sdk/benches/metric.rs
Original file line number Diff line number Diff line change
Expand Up @@ -345,7 +345,9 @@ fn benchmark_collect_histogram(b: &mut Bencher, n: usize) {

b.iter(|| {
let _ = r.collect(&mut rm);
assert_eq!(rm.scope_metrics[0].metrics.len(), n);
// TODO - this assertion fails periodically, and breaks
// our bench testing. We should fix it.
// assert_eq!(rm.scope_metrics[0].metrics.len(), n);
})
}

Expand Down
5 changes: 5 additions & 0 deletions opentelemetry/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,11 @@ harness = false
name = "anyvalue"
harness = false

[[bench]]
name = "context_attach"
harness = false
required-features = ["tracing"]

[lib]
bench = false

Expand Down
110 changes: 110 additions & 0 deletions opentelemetry/benches/context_attach.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
use criterion::{
black_box, criterion_group, criterion_main, measurement::WallTime, BenchmarkGroup, BenchmarkId,
Criterion,
};
use opentelemetry::{
trace::{SpanContext, TraceContextExt},
Context,
};

// Run this benchmark with:
// cargo bench --bench context_attach

fn criterion_benchmark(c: &mut Criterion) {
let span_context = Context::new().with_remote_span_context(SpanContext::empty_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!(benches, criterion_benchmark);

criterion_main!(benches);

0 comments on commit f65ffb7

Please sign in to comment.