QuickBool
A lock-free boolean implementation using atomic operations for high-performance lazy evaluation.
(right now this is experimental and I'm not sure I can actually get it to be faster than LazyLock)
Overview
QuickBool
is a lightweight, lock-free alternative to LazyLock<bool>
that uses atomic operations instead of mutexes for synchronization. It provides a 3-way boolean state:
- Unset: The value hasn't been evaluated yet
- True: The value is true
- False: The value is false
Once set to true or false, the value cannot be changed, making it effectively immutable after initialization.
Features
- Lock-free: Uses atomic operations for thread-safe access without locks
- Zero-cost reads: Once computed, subsequent reads are just atomic loads
- Single computation: The computation function is guaranteed to execute only once
- Thread-safe: Safe for concurrent access from multiple threads
- No dependencies: Pure Rust with no external dependencies
- Reset capability: Can be reset to allow recomputation if needed
License
MIT License - see LICENSE file for details.
Performance
QuickBool
is now the fastest implementation for both first access and cached access, while maintaining all its additional features:
Benchmarks
First Access Performance
xychart-beta
title "First Access Performance Comparison"
x-axis "Implementation" ["LazyLock", "OnceLock", "QuickBool"]
y-axis "Time (nanoseconds)" 0 --> 6
BAR [4.366, 4.755, 1.207]
Cached Access Performance
xychart-beta
title "Cached Access Performance"
x-axis "Implementation" ["LazyLock", "OnceLock", "QuickBool"]
y-axis "Time (nanoseconds)" 0 --> 1
BAR [0.291, 0.438, 0.275]
Usage
Add quick-bool
to your Cargo.toml
:
[]
= "0.1.0"
Basic Usage
use QuickBool;
let quick_bool = new;
// First access computes the value
let value = quick_bool.get_or_set;
// Subsequent access returns the cached value immediately
let cached_value = quick_bool.get_or_set;
assert_eq!;
Checking State
use QuickBool;
let qb = new;
// Check if value has been computed
assert!;
// Get current value without computing
assert_eq!;
// Compute the value
qb.get_or_set;
// Now it's set
assert!;
assert_eq!;
Resetting
use QuickBool;
let qb = new;
qb.get_or_set;
assert!;
// Reset to allow recomputation
qb.reset;
assert!;
// Can compute again
let new_value = qb.get_or_set;
assert_eq!;
Thread-Safe Usage
use QuickBool;
use Arc;
use thread;
let qb = new;
let mut handles = vec!;
// Spawn multiple threads
for _ in 0..4
// Wait for all threads
let results: = handles.into_iter
.map
.collect;
// All threads get the same result
assert!;
Performance-Optimized Usage
For maximum performance when you know the value is cached:
use QuickBool;
let qb = new;
qb.get_or_set;
// Fast cached access when you know it's set
if let Some = qb.get
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
Use Cases
- Configuration flags that are expensive to compute
- Feature flags with complex evaluation logic
- Caching computed boolean results
- Any scenario where you need a thread-safe, lazy boolean with frequent reads