Skip to content

Commit ebea0e4

Browse files
committed
tracing: reorganize benchmarks for comparability (#2178)
Currently, `tracing`'s benchmark suite benchmarks the same behaviors (e.g. creating a span, recording an event, etc) across a handful of cases: with no default dispatcher, with a global default, and with a scoped (thread-local) default. We use criterion's `benchmark_group` to represent each kind of dispatcher, and `bench_function` for each behavior being measured. This is actually kind of backwards relative to how Criterion is _supposed_ to be used. `bench_function` is intended for comparing different implementations of the *same* thing, with the `benchmark_group` representing what's being compared. If we inverted the structure of these benchmarks, Criterion would give us nicer plots that would allow comparing the performance of each dispatch type on the same task. This PR reorganizes the benchmarks so that each behavior being tested (such as entering a span or recording an event) is a `benchmark_group`, and each dispatch type (none, global, or scoped) is a `bench_function` within that group. Now, Criterion will generate plots for each group comparing the performance of each dispatch type in that benchmark. For example, we now get nice comparisons like this: ![image](https://user-images.githubusercontent.com/2796466/175659314-835664ac-a8cf-4b07-91ee-f8cfee77bfbb.png) Unfortunately, this required splitting each benchmark type out into its own file. This is because, once we set the global default dispatcher within one benchmark group, it would remain set for the entire lifetime of the process --- there would be no way to test something else with no global default. But, I think this is fine, even though it means we now have a bunch of tiny files: it also allows us to run an individual benchmark against every combination of dispatch types, without having to run unrelated benches. This is potentially useful if (for example) someone is changing only the code for recording events, and not spans.
1 parent 181bdbe commit ebea0e4

14 files changed

+369
-429
lines changed

tracing/Cargo.toml

+27-3
Original file line numberDiff line numberDiff line change
@@ -68,15 +68,39 @@ attributes = ["tracing-attributes"]
6868
valuable = ["tracing-core/valuable"]
6969

7070
[[bench]]
71-
name = "subscriber"
71+
name = "baseline"
7272
harness = false
7373

7474
[[bench]]
75-
name = "no_subscriber"
75+
name = "dispatch_get_clone"
7676
harness = false
7777

7878
[[bench]]
79-
name = "global_subscriber"
79+
name = "dispatch_get_ref"
80+
harness = false
81+
82+
[[bench]]
83+
name = "empty_span"
84+
harness = false
85+
86+
[[bench]]
87+
name = "enter_span"
88+
harness = false
89+
90+
[[bench]]
91+
name = "event"
92+
harness = false
93+
94+
[[bench]]
95+
name = "span_fields"
96+
harness = false
97+
98+
[[bench]]
99+
name = "span_no_fields"
100+
harness = false
101+
102+
[[bench]]
103+
name = "span_repeated"
80104
harness = false
81105

82106
[badges]

tracing/benches/baseline.rs

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
use criterion::{black_box, criterion_group, criterion_main, Criterion};
2+
3+
fn bench(c: &mut Criterion) {
4+
use std::sync::atomic::{AtomicUsize, Ordering};
5+
6+
let mut group = c.benchmark_group("comparison");
7+
group.bench_function("relaxed_load", |b| {
8+
let foo = AtomicUsize::new(1);
9+
b.iter(|| black_box(foo.load(Ordering::Relaxed)));
10+
});
11+
group.bench_function("acquire_load", |b| {
12+
let foo = AtomicUsize::new(1);
13+
b.iter(|| black_box(foo.load(Ordering::Acquire)))
14+
});
15+
group.bench_function("log", |b| {
16+
b.iter(|| {
17+
log::log!(log::Level::Info, "log");
18+
})
19+
});
20+
group.finish();
21+
}
22+
23+
criterion_group!(benches, bench);
24+
criterion_main!(benches);

tracing/benches/dispatch_get_clone.rs

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
use criterion::{black_box, criterion_group, criterion_main, Criterion};
2+
3+
mod shared;
4+
5+
fn bench(c: &mut Criterion) {
6+
shared::for_all_dispatches(&mut c.benchmark_group("Dispatch::get_clone"), |b| {
7+
b.iter(|| {
8+
let current = tracing::dispatcher::get_default(|current| current.clone());
9+
black_box(current);
10+
})
11+
});
12+
}
13+
14+
criterion_group!(benches, bench);
15+
criterion_main!(benches);

tracing/benches/dispatch_get_ref.rs

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
use criterion::{black_box, criterion_group, criterion_main, Criterion};
2+
3+
mod shared;
4+
5+
fn bench(c: &mut Criterion) {
6+
shared::for_all_dispatches(&mut c.benchmark_group("Dispatch::get_ref"), |b| {
7+
b.iter(|| {
8+
tracing::dispatcher::get_default(|current| {
9+
black_box(&current);
10+
})
11+
})
12+
});
13+
}
14+
15+
criterion_group!(benches, bench);
16+
criterion_main!(benches);

tracing/benches/empty_span.rs

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
use criterion::{black_box, criterion_group, criterion_main, Criterion};
2+
3+
mod shared;
4+
5+
fn bench(c: &mut Criterion) {
6+
let mut group = c.benchmark_group("empty_span");
7+
shared::for_all_dispatches(&mut group, |b| {
8+
b.iter(|| {
9+
let span = tracing::span::Span::none();
10+
black_box(&span);
11+
})
12+
});
13+
group.bench_function("baseline_struct", |b| {
14+
b.iter(|| {
15+
let span = FakeEmptySpan::new();
16+
black_box(&span);
17+
})
18+
});
19+
}
20+
21+
struct FakeEmptySpan {
22+
inner: Option<(usize, std::sync::Arc<()>)>,
23+
meta: Option<&'static ()>,
24+
}
25+
26+
impl FakeEmptySpan {
27+
fn new() -> Self {
28+
Self {
29+
inner: None,
30+
meta: None,
31+
}
32+
}
33+
}
34+
35+
impl Drop for FakeEmptySpan {
36+
fn drop(&mut self) {
37+
black_box(&self.inner);
38+
black_box(&self.meta);
39+
}
40+
}
41+
42+
criterion_group!(benches, bench);
43+
criterion_main!(benches);

tracing/benches/enter_span.rs

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
use criterion::{criterion_group, criterion_main, Criterion};
2+
use tracing::{span, Level};
3+
4+
mod shared;
5+
6+
fn bench(c: &mut Criterion) {
7+
shared::for_all_dispatches(&mut c.benchmark_group("enter_span"), |b| {
8+
let span = span!(Level::TRACE, "span");
9+
b.iter(|| {
10+
let _span = span.enter();
11+
})
12+
});
13+
}
14+
15+
criterion_group!(benches, bench);
16+
criterion_main!(benches);

tracing/benches/event.rs

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
use criterion::{criterion_group, criterion_main, Criterion};
2+
3+
mod shared;
4+
5+
fn bench(c: &mut Criterion) {
6+
shared::for_all_recording(&mut c.benchmark_group("event"), |b| {
7+
b.iter(|| tracing::info!("hello world!"))
8+
});
9+
}
10+
11+
criterion_group!(benches, bench);
12+
criterion_main!(benches);

tracing/benches/global_subscriber.rs

-136
This file was deleted.

0 commit comments

Comments
 (0)