Skip to content

Commit 55cbad0

Browse files
committed
perf: Suppress telemetry using ContextFlags(usize) instead of bool
The code seems to be highly sensitive to alignment, so use a bitfield instead of a boolean.
1 parent 353bbb0 commit 55cbad0

File tree

1 file changed

+26
-7
lines changed

1 file changed

+26
-7
lines changed

opentelemetry/src/context.rs

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -93,11 +93,12 @@ thread_local! {
9393
/// assert_eq!(current.get::<ValueB>(), None);
9494
/// ```
9595
#[derive(Clone, Default)]
96+
#[repr(C)]
9697
pub struct Context {
9798
#[cfg(feature = "trace")]
9899
pub(crate) span: Option<Arc<SynchronizedSpan>>,
99100
entries: Option<Arc<EntryMap>>,
100-
suppress_telemetry: bool,
101+
flags: ContextFlags,
101102
}
102103

103104
type EntryMap = HashMap<TypeId, Arc<dyn Any + Sync + Send>, BuildHasherDefault<IdHasher>>;
@@ -245,7 +246,7 @@ impl Context {
245246
entries,
246247
#[cfg(feature = "trace")]
247248
span: self.span.clone(),
248-
suppress_telemetry: self.suppress_telemetry,
249+
flags: self.flags,
249250
}
250251
}
251252

@@ -335,7 +336,7 @@ impl Context {
335336
/// Returns whether telemetry is suppressed in this context.
336337
#[inline]
337338
pub fn is_telemetry_suppressed(&self) -> bool {
338-
self.suppress_telemetry
339+
self.flags.is_telemetry_suppressed()
339340
}
340341

341342
/// Returns a new context with telemetry suppression enabled.
@@ -344,7 +345,7 @@ impl Context {
344345
entries: self.entries.clone(),
345346
#[cfg(feature = "trace")]
346347
span: self.span.clone(),
347-
suppress_telemetry: true,
348+
flags: self.flags.with_telemetry_suppressed(),
348349
}
349350
}
350351

@@ -413,7 +414,7 @@ impl Context {
413414
Self::map_current(|cx| Context {
414415
span: Some(Arc::new(value)),
415416
entries: cx.entries.clone(),
416-
suppress_telemetry: cx.suppress_telemetry,
417+
flags: cx.flags,
417418
})
418419
}
419420

@@ -422,7 +423,7 @@ impl Context {
422423
Context {
423424
span: Some(Arc::new(value)),
424425
entries: self.entries.clone(),
425-
suppress_telemetry: self.suppress_telemetry,
426+
flags: self.flags,
426427
}
427428
}
428429
}
@@ -446,7 +447,7 @@ impl fmt::Debug for Context {
446447
let entries = self.entries.as_ref().map_or(0, |e| e.len());
447448

448449
dbg.field("entries count", &entries)
449-
.field("suppress_telemetry", &self.suppress_telemetry)
450+
.field("suppress_telemetry", &self.flags.is_telemetry_suppressed())
450451
.finish()
451452
}
452453
}
@@ -502,6 +503,7 @@ impl Hasher for IdHasher {
502503
/// [`ContextGuard`] instances that are constructed using ids from it can't be
503504
/// moved to other threads. That means that the ids are always valid and that
504505
/// they are always within the bounds of the stack.
506+
#[repr(C)]
505507
struct ContextStack {
506508
/// This is the current [`Context`] that is active on this thread, and the top
507509
/// of the [`ContextStack`]. It is always present, and if the `stack` is empty
@@ -605,6 +607,23 @@ impl Default for ContextStack {
605607
}
606608
}
607609

610+
#[derive(Clone, Copy, Default)]
611+
struct ContextFlags(usize);
612+
613+
impl ContextFlags {
614+
const TELEMETRY_SUPPRESSED: usize = 1;
615+
616+
#[inline(always)]
617+
fn is_telemetry_suppressed(&self) -> bool {
618+
self.0 & Self::TELEMETRY_SUPPRESSED != 0
619+
}
620+
621+
#[inline(always)]
622+
fn with_telemetry_suppressed(&self) -> Self {
623+
Self(self.0 | Self::TELEMETRY_SUPPRESSED)
624+
}
625+
}
626+
608627
#[cfg(test)]
609628
mod tests {
610629
use super::*;

0 commit comments

Comments
 (0)