Crates.io | smol_bitmap |
lib.rs | smol_bitmap |
version | 0.3.1 |
created_at | 2025-09-03 23:41:29.356015+00 |
updated_at | 2025-09-19 02:38:37.158274+00 |
description | A space-efficient bitmap with inline storage optimization for small bitmaps |
homepage | https://github.com/can1357/smol_bitmap |
repository | https://github.com/can1357/smol_bitmap |
max_upload_size | |
id | 1823371 |
size | 321,029 |
A space-efficient bitmap implementation with inline storage optimization for Rust.
no_std
support with alloc
for embedded systemsAdd to your Cargo.toml
:
[dependencies]
smol_bitmap = "0.3.1"
use smol_bitmap::SmolBitmap;
fn main() {
let mut bitmap = SmolBitmap::new();
// Set some bits
bitmap.insert(5);
bitmap.insert(10);
bitmap.insert(100);
// Check if bits are set
assert!(bitmap.get(5));
assert!(!bitmap.get(6));
// Count set bits
assert_eq!(bitmap.count_ones(), 3);
// Iterate over set bits
for bit in bitmap.iter() {
println!("Bit {} is set", bit);
}
}
use smol_bitmap::SmolBitmap;
fn main() {
let mut a = SmolBitmap::new();
a.insert(1);
a.insert(2);
a.insert(3);
let mut b = SmolBitmap::new();
b.insert(2);
b.insert(3);
b.insert(4);
// Union: {1, 2, 3, 4}
let union = a.union(&b);
// Intersection: {2, 3}
let intersection = a.intersection(&b);
// Difference: {1}
let difference = a.difference(&b);
// Symmetric difference: {1, 4}
let sym_diff = a.symmetric_difference(&b);
}
use smol_bitmap::SmolBitmap;
fn main() {
let mut bitmap = SmolBitmap::new();
// Reserve capacity for 500 bits
bitmap.reserve(500);
// Bulk operations
bitmap.extend([10, 20, 30, 40, 50]);
// Retain only even indices
bitmap.retain(|bit| bit % 2 == 0);
// Find next/previous set bits
assert_eq!(bitmap.next_set_bit(15), Some(20));
assert_eq!(bitmap.prev_set_bit(35), Some(30));
// Toggle bits
bitmap.complement(25);
// Create from iterator
let from_iter: SmolBitmap = (0..10).step_by(2).collect();
}
SmolBitmap uses a hybrid storage strategy optimized for both small and large bitmaps:
Vec<u64>
when neededPerformance comparison with bitvec
(lower is better):
Operation | Size | SmolBitmap | BitVec | Winner |
---|---|---|---|---|
Creation | 100 bits | 2.6ns | 15.7ns | SmolBitmap (6.0x faster) |
1000 bits | 11.4ns | 14.1ns | SmolBitmap (1.2x faster) | |
10000 bits | 47.5ns | 66.3ns | SmolBitmap (1.4x faster) | |
Set bit | 100 bits | 12.8ns | 28.3ns | SmolBitmap (2.2x faster) |
1000 bits | 132.6ns | 97.2ns | BitVec (1.4x faster) | |
10000 bits | 163.8ns | 138.8ns | BitVec (1.2x faster) | |
Get bit ¹ | 100 bits | 528ns | 514ns | - |
1000 bits | 648ns | 535ns | BitVec (1.2x faster) | |
10000 bits | 624ns | 509ns | BitVec (1.2x faster) | |
Iteration ² | 100 bits | 19.3ns | 71.9ns | SmolBitmap (3.7x faster) |
1000 bits | 376ns | 701ns | SmolBitmap (1.9x faster) | |
10000 bits | 3.98µs | 6.32µs | SmolBitmap (1.6x faster) | |
Count ones | 100 bits | 2.2ns | 3.0ns | SmolBitmap (1.4x faster) |
1000 bits | 1.8ns | 6.8ns | SmolBitmap (3.8x faster) | |
10000 bits | 17.4ns | 11.1ns | BitVec (1.6x faster) |
¹ Time for N get operations
² Sparse bitmap iteration (every 10th bit set)
Key Advantages:
Run benchmarks yourself:
cargo bench
✅ Best when:
❌ Prefer alternatives when:
bit-vec
/ bitvec
fixedbitset
roaring
See the examples/
directory for more usage examples:
# Basic usage
cargo run --example basic
# Advanced features
cargo run --example advanced
std
(default) - Use standard library (provides Error
trait implementation)serde
- Enable serialization/deserialization supportSmolBitmap supports no_std
environments with alloc
:
[dependencies]
smol_bitmap = { version = "0.3.1", default-features = false }
This will disable the std
feature but still requires an allocator for heap storage when bitmaps exceed inline capacity.
SmolBitmap uses unsafe
code in a few performance-critical areas. All unsafe usage is:
Contributions are welcome! Please feel free to submit a Pull Request.
This project is licensed under the MIT license.