use criterion::{black_box, criterion_group, criterion_main, Criterion};
use quick_bool::QuickBool;
use std::sync::LazyLock;
use std::sync::OnceLock;
fn expensive_computation() -> bool {
let mut result = 0;
for i in 0..1000 {
result += i * i;
}
result % 2 == 0
}
fn benchmark_quick_bool(c: &mut Criterion) {
let mut group = c.benchmark_group("QuickBool");
group.bench_function("first_access", |b| {
b.iter(|| {
let qb = QuickBool::new();
black_box(qb.get_or_set(expensive_computation));
});
});
group.bench_function("cached_access", |b| {
let qb = QuickBool::new();
qb.get_or_set(expensive_computation);
b.iter(|| {
black_box(qb.get_or_set(|| panic!("Should not execute")));
});
});
group.bench_function("concurrent_access", |b| {
b.iter(|| {
use std::sync::Arc;
use std::thread;
let qb = Arc::new(QuickBool::new());
let mut handles = vec![];
for _ in 0..4 {
let qb_clone = Arc::clone(&qb);
let handle = thread::spawn(move || {
qb_clone.get_or_set(expensive_computation)
});
handles.push(handle);
}
let results: Vec<bool> = handles.into_iter()
.map(|h| h.join().unwrap())
.collect();
black_box(results);
});
});
group.finish();
}
fn benchmark_lazy_lock(c: &mut Criterion) {
let mut group = c.benchmark_group("LazyLock");
group.bench_function("first_access", |b| {
b.iter(|| {
let lazy_bool = LazyLock::new(expensive_computation);
black_box(*lazy_bool);
});
});
group.bench_function("cached_access", |b| {
let lazy_bool = LazyLock::new(expensive_computation);
black_box(*lazy_bool);
b.iter(|| {
black_box(*lazy_bool);
});
});
group.bench_function("concurrent_access", |b| {
b.iter(|| {
use std::sync::Arc;
use std::thread;
let lazy_bool = Arc::new(LazyLock::new(expensive_computation));
let mut handles = vec![];
for _ in 0..4 {
let lazy_clone = Arc::clone(&lazy_bool);
let handle = thread::spawn(move || {
**lazy_clone
});
handles.push(handle);
}
let results: Vec<bool> = handles.into_iter()
.map(|h| h.join().unwrap())
.collect();
black_box(results);
});
});
group.finish();
}
fn benchmark_once_lock(c: &mut Criterion) {
let mut group = c.benchmark_group("OnceLock");
group.bench_function("first_access", |b| {
b.iter(|| {
let once_bool = OnceLock::new();
black_box(once_bool.get_or_init(expensive_computation));
});
});
group.bench_function("cached_access", |b| {
let once_bool = OnceLock::new();
once_bool.get_or_init(expensive_computation);
b.iter(|| {
black_box(once_bool.get().unwrap());
});
});
group.bench_function("concurrent_access", |b| {
b.iter(|| {
use std::sync::Arc;
use std::thread;
let once_bool = Arc::new(OnceLock::new());
let mut handles = vec![];
for _ in 0..4 {
let once_clone = Arc::clone(&once_bool);
let handle = thread::spawn(move || {
let value = *once_clone.get_or_init(expensive_computation);
black_box(value)
});
handles.push(handle);
}
let results: Vec<bool> = handles.into_iter()
.map(|h| h.join().unwrap())
.collect();
black_box(results);
});
});
group.finish();
}
fn benchmark_comparison(c: &mut Criterion) {
let mut group = c.benchmark_group("Comparison");
group.bench_function("QuickBool_first", |b| {
b.iter(|| {
let qb = QuickBool::new();
black_box(qb.get_or_set(expensive_computation));
});
});
group.bench_function("LazyLock_first", |b| {
b.iter(|| {
let lazy_bool = LazyLock::new(expensive_computation);
black_box(*lazy_bool);
});
});
group.bench_function("OnceLock_first", |b| {
b.iter(|| {
let once_bool = OnceLock::new();
black_box(once_bool.get_or_init(expensive_computation));
});
});
group.bench_function("QuickBool_cached", |b| {
let qb = QuickBool::new();
qb.get_or_set(expensive_computation);
b.iter(|| {
black_box(qb.get_or_set(|| panic!("Should not execute")));
});
});
group.bench_function("LazyLock_cached", |b| {
let lazy_bool = LazyLock::new(expensive_computation);
black_box(*lazy_bool);
b.iter(|| {
black_box(*lazy_bool);
});
});
group.bench_function("OnceLock_cached", |b| {
let once_bool = OnceLock::new();
once_bool.get_or_init(expensive_computation);
b.iter(|| {
black_box(once_bool.get().unwrap());
});
});
group.finish();
}
criterion_group!(
benches,
benchmark_quick_bool,
benchmark_lazy_lock,
benchmark_once_lock,
benchmark_comparison
);
criterion_main!(benches);