From c2530af9549703aed0c569b789479a8d4129567f Mon Sep 17 00:00:00 2001 From: fereidani Date: Mon, 15 Dec 2025 00:24:37 +0330 Subject: [PATCH 1/5] Add benchmark for `to_bytes` --- benches/bench.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/benches/bench.rs b/benches/bench.rs index d5915d4..b78b934 100644 --- a/benches/bench.rs +++ b/benches/bench.rs @@ -42,6 +42,18 @@ fn bench_usize_small(b: &mut Bencher) { }); } +#[bench] +fn bench_to_bytes(b: &mut Bencher) { + let mut bit_vec = BitVec::from_elem(BENCH_BITS, false); + let mut r = small_rng(); + for _ in 0..BENCH_BITS / 10 { + bit_vec.set((r.next_u32() as usize) % BENCH_BITS, true); + } + b.iter(|| { + black_box(bit_vec.to_bytes()); + }); +} + #[bench] fn bench_bit_set_big_fixed(b: &mut Bencher) { let mut r = small_rng(); From a852a24326973ed31741cf48ded66f22da573598 Mon Sep 17 00:00:00 2001 From: fereidani Date: Mon, 15 Dec 2025 00:25:27 +0330 Subject: [PATCH 2/5] Optimize `to_bytes` --- src/lib.rs | 45 +++++++++++++++++++++++++-------------------- 1 file changed, 25 insertions(+), 20 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index ad32249..a3cc587 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1322,30 +1322,35 @@ impl BitVec { /// assert_eq!(bv.to_bytes(), [0b00100000, 0b10000000]); /// ``` pub fn to_bytes(&self) -> Vec { + static REVERSE_TABLE: [u8; 256] = { + let mut tbl = [0u8; 256]; + let mut i: u8 = 0; + loop { + tbl[i as usize] = i.reverse_bits(); + if i == 255 { + break; + } + i += 1; + } + tbl + }; self.ensure_invariant(); - // Oh lord, we're mapping this to bytes bit-by-bit! - fn bit(bit_vec: &BitVec, byte: usize, bit: usize) -> u8 { - let offset = byte * 8 + bit; - if offset >= bit_vec.nbits { - 0 - } else { - (bit_vec[offset] as u8) << (7 - bit) + + let len = self.nbits / 8 + if self.nbits % 8 == 0 { 0 } else { 1 }; + let mut result = Vec::with_capacity(len); + + for byte_idx in 0..len { + let mut byte = 0u8; + for bit_idx in 0..8 { + let offset = byte_idx * 8 + bit_idx; + if offset < self.nbits && self[offset] { + byte |= 1 << bit_idx; + } } + result.push(REVERSE_TABLE[byte as usize]); } - let len = self.nbits / 8 + if self.nbits % 8 == 0 { 0 } else { 1 }; - (0..len) - .map(|i| { - bit(self, i, 0) - | bit(self, i, 1) - | bit(self, i, 2) - | bit(self, i, 3) - | bit(self, i, 4) - | bit(self, i, 5) - | bit(self, i, 6) - | bit(self, i, 7) - }) - .collect() + result } /// Compares a `BitVec` to a slice of `bool`s. From 7b7f54fe50b1a6230568a4327118ff14392e896d Mon Sep 17 00:00:00 2001 From: Peter Blackson Date: Sat, 28 Feb 2026 16:33:08 +0100 Subject: [PATCH 3/5] Remove unnecessary parentheses --- src/lib.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index a3cc587..a49a88f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -826,7 +826,7 @@ impl BitVec { pub fn or(&mut self, other: &Self) -> bool { self.ensure_invariant(); debug_assert!(other.is_last_block_fixed()); - self.process(other, |w1, w2| (w1 | w2)) + self.process(other, |w1, w2| w1 | w2) } /// Calculates the bitwise `and` of two bitvectors. @@ -857,7 +857,7 @@ impl BitVec { pub fn and(&mut self, other: &Self) -> bool { self.ensure_invariant(); debug_assert!(other.is_last_block_fixed()); - self.process(other, |w1, w2| (w1 & w2)) + self.process(other, |w1, w2| w1 & w2) } /// Calculates the difference between two bitvectors. @@ -896,7 +896,7 @@ impl BitVec { pub fn difference(&mut self, other: &Self) -> bool { self.ensure_invariant(); debug_assert!(other.is_last_block_fixed()); - self.process(other, |w1, w2| (w1 & !w2)) + self.process(other, |w1, w2| w1 & !w2) } /// Calculates the xor of two bitvectors. @@ -927,7 +927,7 @@ impl BitVec { pub fn xor(&mut self, other: &Self) -> bool { self.ensure_invariant(); debug_assert!(other.is_last_block_fixed()); - self.process(other, |w1, w2| (w1 ^ w2)) + self.process(other, |w1, w2| w1 ^ w2) } /// Calculates the nand of two bitvectors. From 0378b6501b40519d9af8276086d8a7b199fcee7b Mon Sep 17 00:00:00 2001 From: Peter Blackson Date: Sat, 28 Feb 2026 16:36:42 +0100 Subject: [PATCH 4/5] Bump MSRV to 1.71 --- .github/workflows/rust.yml | 2 +- Cargo.toml | 2 +- README.md | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 3d293d4..e0b5754 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -54,7 +54,7 @@ jobs: strategy: fail-fast: false matrix: - rust: [1.67.0, 1.68.0] + rust: [1.71.0, 1.72.0] timeout-minutes: 45 steps: - uses: actions/checkout@v5 diff --git a/Cargo.toml b/Cargo.toml index b5a88ef..e3feeac 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,7 +10,7 @@ documentation = "https://docs.rs/bit-vec/" keywords = ["data-structures", "bitvec", "bitmask", "bitmap", "bit"] readme = "README.md" edition = "2021" -rust-version = "1.67" +rust-version = "1.71" [dependencies] borsh = { version = "1.5.5", default-features = false, features = ["derive"], optional = true } diff --git a/README.md b/README.md index d7eb919..0abd23d 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ [![crates.io][crates.io shield]][crates.io link] [![Documentation][docs.rs badge]][docs.rs link] ![Rust CI][github ci badge] -![MSRV][rustc 1.67+] +![MSRV][rustc 1.71+]

[![Dependency Status][deps.rs status]][deps.rs link] @@ -21,8 +21,8 @@ [crates.io link]: https://crates.io/crates/bit-vec [docs.rs badge]: https://docs.rs/bit-vec/badge.svg?version=0.8.0 [docs.rs link]: https://docs.rs/bit-vec/0.8.0/bit_vec/ -[github ci badge]: https://github.com/contain-rs/bit-vec/workflows/Rust/badge.svg?branch=master -[rustc 1.67+]: https://img.shields.io/badge/rustc-1.67%2B-blue.svg +[github ci badge]: https://github.com/contain-rs/bit-vec/actions/workflows/rust.yml/badge.svg +[rustc 1.71+]: https://img.shields.io/badge/rustc-1.71%2B-blue.svg [deps.rs status]: https://deps.rs/crate/bit-vec/0.8.0/status.svg [deps.rs link]: https://deps.rs/crate/bit-vec/0.8.0 [shields.io download count]: https://img.shields.io/crates/d/bit-vec.svg From 473febf6181aa7a2a90f01e0dfa54464810ee835 Mon Sep 17 00:00:00 2001 From: Peter Blackson Date: Sat, 28 Feb 2026 16:39:09 +0100 Subject: [PATCH 5/5] Bump MSRV to 1.82 --- .github/workflows/rust.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index e0b5754..a427559 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -54,7 +54,7 @@ jobs: strategy: fail-fast: false matrix: - rust: [1.71.0, 1.72.0] + rust: [1.76.0, 1.77.0] timeout-minutes: 45 steps: - uses: actions/checkout@v5