1 extern crate criterion
;
4 use criterion
::{black_box, criterion_group, criterion_main, Criterion}
;
9 sync
::{Mutex, MutexGuard}
,
11 use tracing
::{field, span, Event, Id, Metadata}
;
13 /// A subscriber that is enabled but otherwise does nothing.
14 struct EnabledSubscriber
;
16 impl tracing
::Subscriber
for EnabledSubscriber
{
17 fn new_span(&self, span
: &span
::Attributes
<'_
>) -> Id
{
19 Id
::from_u64(0xDEAD_FACE)
22 fn event(&self, event
: &Event
<'_
>) {
26 fn record(&self, span
: &Id
, values
: &span
::Record
<'_
>) {
27 let _
= (span
, values
);
30 fn record_follows_from(&self, span
: &Id
, follows
: &Id
) {
31 let _
= (span
, follows
);
34 fn enabled(&self, metadata
: &Metadata
<'_
>) -> bool
{
39 fn enter(&self, span
: &Id
) {
43 fn exit(&self, span
: &Id
) {
48 /// Simulates a subscriber that records span data.
49 struct VisitingSubscriber(Mutex
<String
>);
51 struct Visitor
<'a
>(MutexGuard
<'a
, String
>);
53 impl<'a
> field
::Visit
for Visitor
<'a
> {
54 fn record_debug(&mut self, _field
: &field
::Field
, value
: &dyn fmt
::Debug
) {
56 let _
= write
!(&mut *self.0, "{:?}", value
);
60 impl tracing
::Subscriber
for VisitingSubscriber
{
61 fn new_span(&self, span
: &span
::Attributes
<'_
>) -> Id
{
62 let mut visitor
= Visitor(self.0.lock().unwrap());
63 span
.record(&mut visitor
);
64 Id
::from_u64(0xDEAD_FACE)
67 fn record(&self, _span
: &Id
, values
: &span
::Record
<'_
>) {
68 let mut visitor
= Visitor(self.0.lock().unwrap());
69 values
.record(&mut visitor
);
72 fn event(&self, event
: &Event
<'_
>) {
73 let mut visitor
= Visitor(self.0.lock().unwrap());
74 event
.record(&mut visitor
);
77 fn record_follows_from(&self, span
: &Id
, follows
: &Id
) {
78 let _
= (span
, follows
);
81 fn enabled(&self, metadata
: &Metadata
<'_
>) -> bool
{
86 fn enter(&self, span
: &Id
) {
90 fn exit(&self, span
: &Id
) {
95 const N_SPANS
: usize = 100;
97 fn criterion_benchmark(c
: &mut Criterion
) {
98 c
.bench_function("span_no_fields", |b
| {
99 tracing
::subscriber
::with_default(EnabledSubscriber
, || {
100 b
.iter(|| span
!(Level
::TRACE
, "span"))
104 c
.bench_function("enter_span", |b
| {
105 tracing
::subscriber
::with_default(EnabledSubscriber
, || {
106 let span
= span
!(Level
::TRACE
, "span");
107 #[allow(clippy::unit_arg)]
108 b
.iter(|| black_box(span
.in_scope(|| {}
)))
112 c
.bench_function("span_repeatedly", |b
| {
114 fn mk_span(i
: u64) -> tracing
::Span
{
115 span
!(Level
::TRACE
, "span", i
= i
)
118 let n
= black_box(N_SPANS
);
119 tracing
::subscriber
::with_default(EnabledSubscriber
, || {
120 b
.iter(|| (0..n
).fold(mk_span(0), |_
, i
| mk_span(i
as u64)))
124 c
.bench_function("span_with_fields", |b
| {
125 tracing
::subscriber
::with_default(EnabledSubscriber
, || {
133 quuux
= tracing
::field
::debug(0.99)
139 c
.bench_function("span_with_fields_record", |b
| {
140 let subscriber
= VisitingSubscriber(Mutex
::new(String
::from("")));
141 tracing
::subscriber
::with_default(subscriber
, || {
149 quuux
= tracing
::field
::debug(0.99)
156 fn bench_dispatch(c
: &mut Criterion
) {
157 let mut group
= c
.benchmark_group("dispatch");
158 group
.bench_function("no_dispatch_get_ref", |b
| {
160 tracing
::dispatcher
::get_default(|current
| {
165 group
.bench_function("no_dispatch_get_clone", |b
| {
167 let current
= tracing
::dispatcher
::get_default(|current
| current
.clone());
171 group
.bench_function("get_ref", |b
| {
172 tracing
::subscriber
::with_default(EnabledSubscriber
, || {
174 tracing
::dispatcher
::get_default(|current
| {
180 group
.bench_function("get_clone", |b
| {
181 tracing
::subscriber
::with_default(EnabledSubscriber
, || {
183 let current
= tracing
::dispatcher
::get_default(|current
| current
.clone());
191 criterion_group
!(benches
, criterion_benchmark
, bench_dispatch
);
192 criterion_main
!(benches
);