Skip to content

Instantly share code, notes, and snippets.

@qatoqat
Created March 6, 2025 10:37
Show Gist options
  • Select an option

  • Save qatoqat/b5d047791be0f5d0fb1feb88f479bcf2 to your computer and use it in GitHub Desktop.

Select an option

Save qatoqat/b5d047791be0f5d0fb1feb88f479bcf2 to your computer and use it in GitHub Desktop.
Benchmark local vs shared bool access
// Local bool access: 384.0872ms
// Arc<bool> access: 337.0548ms
// Arc<AtomicBool> access: 665.9188ms
// Weak<AtomicBool> upgrade & access (valid): 19.8125438s
// Weak<bool> upgrade & access (valid): 17.187099s
// Weak<AtomicBool> upgrade & access (dropped): 19.7792422s
// Weak<bool> upgrade & access (dropped): 17.5252546s
use std::sync::{Arc, Weak};
use std::sync::atomic::{AtomicBool, Ordering};
use std::time::Instant;
struct MyStruct {
local_flag: bool, // Direct access bool (fastest)
shared_atomic: Arc<AtomicBool>, // Shared atomic bool
shared_arc: Arc<bool>, // Shared non-atomic bool
}
struct Checker {
weak_atomic: Weak<AtomicBool>,
weak_arc: Weak<bool>,
}
impl MyStruct {
fn new() -> Self {
Self {
local_flag: false,
shared_atomic: Arc::new(AtomicBool::new(false)),
shared_arc: Arc::new(false),
}
}
fn get_checker(&self) -> Checker {
Checker {
weak_atomic: Arc::downgrade(&self.shared_atomic),
weak_arc: Arc::downgrade(&self.shared_arc),
}
}
}
fn benchmark<F: Fn()>(name: &str, iterations: usize, func: F) {
let start = Instant::now();
for _ in 0..iterations {
func();
}
let duration = start.elapsed();
println!("{}: {:?}", name, duration);
}
fn main() {
let iterations = 1_000_000_000; // Adjust as needed
// Initialize struct
let mut my_struct = MyStruct::new();
let checker = my_struct.get_checker();
// Local bool test (fastest)
benchmark("Local bool access", iterations, || {
let _ = my_struct.local_flag;
std::hint::black_box(my_struct.local_flag);
});
// Arc<bool> test (heap access, but no atomic operations)
let shared_arc = my_struct.shared_arc.clone();
benchmark("Arc<bool> access", iterations, || {
let _ = *shared_arc;
std::hint::black_box(*shared_arc);
});
// Arc<AtomicBool> test (heap access + atomic load)
let shared_atomic = my_struct.shared_atomic.clone();
benchmark("Arc<AtomicBool> access", iterations, || {
let _ = shared_atomic.load(Ordering::SeqCst);
std::hint::black_box(shared_atomic.load(Ordering::SeqCst));
});
// Weak<AtomicBool> access (before drop)
let weak_atomic = checker.weak_atomic.clone();
benchmark("Weak<AtomicBool> upgrade & access (valid)", iterations, || {
if let Some(flag) = weak_atomic.upgrade() {
let _ = flag.load(Ordering::SeqCst);
std::hint::black_box(flag.load(Ordering::SeqCst));
}
});
// Weak<bool> access (before drop)
let weak_arc = checker.weak_arc.clone();
benchmark("Weak<bool> upgrade & access (valid)", iterations, || {
if let Some(flag) = weak_arc.upgrade() {
let _ = *flag;
std::hint::black_box(*flag);
}
});
// Drop Arc references
drop(shared_atomic);
drop(shared_arc);
// Weak<AtomicBool> access (after drop)
benchmark("Weak<AtomicBool> upgrade & access (dropped)", iterations, || {
if let Some(flag) = weak_atomic.upgrade() {
let _ = flag.load(Ordering::SeqCst);
std::hint::black_box(flag.load(Ordering::SeqCst));
}
});
// Weak<bool> access (after drop)
benchmark("Weak<bool> upgrade & access (dropped)", iterations, || {
if let Some(flag) = weak_arc.upgrade() {
let _ = *flag;
std::hint::black_box(*flag);
}
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment