Skip to content

Commit f65ffb7

Browse files
authored
Merge branch 'main' into cijothomas/example-tracer-reuse
2 parents 5d86c8b + 4830a3c commit f65ffb7

File tree

5 files changed

+185
-11
lines changed

5 files changed

+185
-11
lines changed
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
on: [pull_request]
2+
name: benchmark pull requests
3+
jobs:
4+
runBenchmark:
5+
name: run benchmark
6+
permissions:
7+
pull-requests: write
8+
runs-on: ubuntu-latest
9+
steps:
10+
- uses: actions/checkout@v3
11+
- uses: arduino/setup-protoc@v3
12+
- uses: dtolnay/rust-toolchain@master
13+
with:
14+
toolchain: stable
15+
- uses: boa-dev/criterion-compare-action@v3
16+
with:
17+
cwd: opentelemetry
18+
branchName: ${{ github.base_ref }}
19+
- uses: boa-dev/criterion-compare-action@v3
20+
with:
21+
cwd: opentelemetry-appender-tracing
22+
features: spec_unstable_logs_enabled
23+
branchName: ${{ github.base_ref }}
24+
- uses: boa-dev/criterion-compare-action@v3
25+
with:
26+
cwd: opentelemetry-sdk
27+
features: rt-tokio,testing,metrics,logs,spec_unstable_metrics_views
28+
branchName: ${{ github.base_ref }}

opentelemetry-sdk/benches/context.rs

Lines changed: 39 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion, Throughput};
1+
use criterion::{black_box, criterion_group, criterion_main, BenchmarkId, Criterion};
22
use opentelemetry::{
33
global::BoxedTracer,
44
trace::{
@@ -17,7 +17,6 @@ use std::fmt::Display;
1717

1818
fn criterion_benchmark(c: &mut Criterion) {
1919
let mut group = c.benchmark_group("context");
20-
group.throughput(Throughput::Elements(1));
2120
for env in [
2221
Environment::InContext,
2322
Environment::NoContext,
@@ -30,27 +29,57 @@ fn criterion_benchmark(c: &mut Criterion) {
3029
group.bench_function(
3130
BenchmarkId::new("has_active_span", param.clone()),
3231
|b| match api {
33-
Api::Alt => b.iter(|| Context::map_current(TraceContextExt::has_active_span)),
34-
Api::Spec => b.iter(|| Context::current().has_active_span()),
32+
Api::Alt => b.iter(has_active_span_alt),
33+
Api::Spec => b.iter(has_active_span_spec),
3534
},
3635
);
3736
group.bench_function(
3837
BenchmarkId::new("is_sampled", param.clone()),
3938
|b| match api {
40-
Api::Alt => {
41-
b.iter(|| Context::map_current(|cx| cx.span().span_context().is_sampled()))
42-
}
43-
Api::Spec => b.iter(|| Context::current().span().span_context().is_sampled()),
39+
Api::Alt => b.iter(is_sampled_alt),
40+
Api::Spec => b.iter(is_sampled_spec),
4441
},
4542
);
4643
group.bench_function(BenchmarkId::new("is_recording", param), |b| match api {
47-
Api::Alt => b.iter(|| Context::map_current(|cx| cx.span().is_recording())),
48-
Api::Spec => b.iter(|| Context::current().span().is_recording()),
44+
Api::Alt => b.iter(is_recording_alt),
45+
Api::Spec => b.iter(is_recording_spec),
4946
});
5047
}
5148
}
5249
}
5350

51+
#[inline(never)]
52+
fn has_active_span_alt() {
53+
let _ = black_box(Context::map_current(TraceContextExt::has_active_span));
54+
}
55+
56+
#[inline(never)]
57+
fn has_active_span_spec() {
58+
let _ = black_box(Context::current().has_active_span());
59+
}
60+
61+
#[inline(never)]
62+
fn is_sampled_alt() {
63+
let _ = black_box(Context::map_current(|cx| {
64+
cx.span().span_context().is_sampled()
65+
}));
66+
}
67+
68+
#[inline(never)]
69+
fn is_sampled_spec() {
70+
let _ = black_box(Context::current().span().span_context().is_sampled());
71+
}
72+
73+
#[inline(never)]
74+
fn is_recording_alt() {
75+
let _ = black_box(Context::map_current(|cx| cx.span().is_recording()));
76+
}
77+
78+
#[inline(never)]
79+
fn is_recording_spec() {
80+
let _ = black_box(Context::current().span().is_recording());
81+
}
82+
5483
#[derive(Copy, Clone)]
5584
enum Api {
5685
/// An alternative way which may be faster than what the spec recommends.

opentelemetry-sdk/benches/metric.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -345,7 +345,9 @@ fn benchmark_collect_histogram(b: &mut Bencher, n: usize) {
345345

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

opentelemetry/Cargo.toml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,11 @@ harness = false
5757
name = "anyvalue"
5858
harness = false
5959

60+
[[bench]]
61+
name = "context_attach"
62+
harness = false
63+
required-features = ["tracing"]
64+
6065
[lib]
6166
bench = false
6267

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
use criterion::{
2+
black_box, criterion_group, criterion_main, measurement::WallTime, BenchmarkGroup, BenchmarkId,
3+
Criterion,
4+
};
5+
use opentelemetry::{
6+
trace::{SpanContext, TraceContextExt},
7+
Context,
8+
};
9+
10+
// Run this benchmark with:
11+
// cargo bench --bench context_attach
12+
13+
fn criterion_benchmark(c: &mut Criterion) {
14+
let span_context = Context::new().with_remote_span_context(SpanContext::empty_context());
15+
let contexts = vec![
16+
("empty_cx", Context::new()),
17+
("single_value_cx", Context::new().with_value(Value(4711))),
18+
("span_cx", span_context),
19+
];
20+
for (name, cx) in contexts {
21+
single_cx_scope(&mut group(c), name, &cx);
22+
nested_cx_scope(&mut group(c), name, &cx);
23+
overlapping_cx_scope(&mut group(c), name, &cx);
24+
}
25+
}
26+
27+
fn single_cx_scope(
28+
group: &mut BenchmarkGroup<'_, WallTime>,
29+
context_type: &str,
30+
context: &Context,
31+
) {
32+
group.bench_function(BenchmarkId::new("single_cx", context_type), |b| {
33+
b.iter_batched(
34+
|| context.clone(),
35+
|cx| {
36+
single_cx(cx);
37+
},
38+
criterion::BatchSize::SmallInput,
39+
);
40+
});
41+
}
42+
43+
#[inline(never)]
44+
fn single_cx(cx: Context) {
45+
let _cx_guard = black_box(cx.attach());
46+
let _ = black_box(dummy_work());
47+
}
48+
49+
fn nested_cx_scope(group: &mut BenchmarkGroup<'_, WallTime>, cx_type: &str, context: &Context) {
50+
group.bench_function(BenchmarkId::new("nested_cx", cx_type), |b| {
51+
b.iter_batched(
52+
|| (context.clone(), context.clone()),
53+
|(cx1, cx2)| {
54+
nested_cx(cx1, cx2);
55+
},
56+
criterion::BatchSize::SmallInput,
57+
);
58+
});
59+
}
60+
61+
#[inline(never)]
62+
fn nested_cx(cx1: Context, cx2: Context) {
63+
let _outer_cx_guard = black_box(cx1.attach());
64+
let _inner_cx_guard = black_box(cx2.attach());
65+
let _ = black_box(dummy_work());
66+
}
67+
68+
fn overlapping_cx_scope(
69+
group: &mut BenchmarkGroup<'_, WallTime>,
70+
cx_type: &str,
71+
context: &Context,
72+
) {
73+
// This is to ensure that the context is restored after the benchmark,
74+
// see https://github.com/open-telemetry/opentelemetry-rust/issues/1887
75+
let _restore_cx_guard = Context::current().attach();
76+
group.bench_function(BenchmarkId::new("out_of_order_cx_drop", cx_type), |b| {
77+
b.iter_batched(
78+
|| (context.clone(), context.clone()),
79+
|(cx1, cx2)| {
80+
out_of_order_cx_drop(cx1, cx2);
81+
},
82+
criterion::BatchSize::SmallInput,
83+
);
84+
});
85+
}
86+
87+
#[inline(never)]
88+
fn out_of_order_cx_drop(cx1: Context, cx2: Context) {
89+
let outer_cx_guard = cx1.attach();
90+
let inner_cx_guard = cx2.attach();
91+
let _ = black_box(dummy_work());
92+
drop(outer_cx_guard);
93+
drop(inner_cx_guard);
94+
}
95+
96+
#[inline(never)]
97+
fn dummy_work() -> i32 {
98+
black_box(1 + 1)
99+
}
100+
101+
fn group(c: &mut Criterion) -> BenchmarkGroup<WallTime> {
102+
c.benchmark_group("context_attach")
103+
}
104+
105+
#[derive(Debug, PartialEq)]
106+
struct Value(i32);
107+
108+
criterion_group!(benches, criterion_benchmark);
109+
110+
criterion_main!(benches);

0 commit comments

Comments
 (0)