Skip to main content

bitio_rs/fast/
reader.rs

1use crate::error::BitReadWriteError;
2use std::io::{Read, Result};
3
4/// Ultra-fast bit reader for BigEndian streams (~18x faster than standard)
5///
6/// ## Critical Performance Notice
7/// - This implementation does **NOT** implement the standard `BitRead` trait to avoid abstraction overhead and enable aggressive optimizations.
8/// - API **intentionally** differs from standard implementations to ensure users are clearly aware they are using an incompatible version.
9///
10/// ## Performance Characteristics (Mac mini M4 16GB benchmark)
11/// - Reading 32 bits: ~290 ns (nanoseconds)
12/// - ~18x faster than standard `BitReader`
13///
14/// ⚠️ **Use at your own risk**
15pub struct FastBitReaderBig<R: Read> {
16    raw: R,
17    buffer: u64,
18    bits_available: usize,
19    scratch: [u8; 8],
20}
21
22impl<R: Read> FastBitReaderBig<R> {
23    #[inline]
24    pub fn new(raw: R) -> Self {
25        Self {
26            raw,
27            buffer: 0,
28            bits_available: 0,
29            scratch: [0; 8],
30        }
31    }
32
33    /// Reads 1..=64 bits with maximal performance
34    #[inline(always)]
35    pub fn read_bits_fast(&mut self, n: usize) -> Result<u64> {
36        if n == 0 || n > 64 {
37            return Err(BitReadWriteError::InvalidBitCount(n).into());
38        }
39
40        while self.bits_available < n {
41            let remaining_bits = n - self.bits_available;
42            let max_bytes = (64 - self.bits_available) / 8;
43            let needed_bytes = ((remaining_bits + 7) / 8).min(max_bytes).max(1);
44
45            self.raw.read_exact(&mut self.scratch[..needed_bytes])?;
46
47            let mut val = 0u64;
48            for i in 0..needed_bytes {
49                val = (val << 8) | self.scratch[i] as u64;
50            }
51
52            let new_bits = needed_bytes * 8;
53            let shift = 64 - self.bits_available - new_bits;
54            self.buffer |= val.wrapping_shl(shift as u32);
55            self.bits_available += new_bits;
56        }
57
58        let result = self.buffer >> (64 - n);
59        // 对 n==64 做特殊处理,避免溢出
60        if n < 64 {
61            self.buffer <<= n;
62        } else {
63            self.buffer = 0;
64        }
65        self.bits_available -= n;
66        Ok(result)
67    }
68}
69
70/// Ultra-fast bit reader for LittleEndian streams (~21x faster than standard)
71///
72/// ## Critical Performance Notice
73/// - This implementation does **NOT** implement the standard `BitRead` trait to avoid abstraction overhead and enable aggressive optimizations.
74/// - API **intentionally** differs from standard implementations to ensure users are clearly aware they are using an incompatible version.
75///
76/// ## Performance Characteristics (Mac mini M4 16GB benchmark)
77/// - Reading 32 bits: ~260 ns (nanoseconds)
78/// - ~21x faster than standard `BitReader`
79///
80/// ⚠️ **Use at your own risk**
81pub struct FastBitReaderLittle<R: Read> {
82    raw: R,
83    buffer: u64,
84    bits_available: usize,
85    scratch: [u8; 8],
86}
87
88impl<R: Read> FastBitReaderLittle<R> {
89    #[inline]
90    pub fn new(raw: R) -> Self {
91        Self {
92            raw,
93            buffer: 0,
94            bits_available: 0,
95            scratch: [0; 8],
96        }
97    }
98
99    /// Reads bits with extreme performance (0-64 bits)
100    ///
101    /// Same performance characteristics and safety considerations
102    /// as `FastBitReaderBig::read_bits_fast` but for LittleEndian data.
103    #[inline(always)]
104    pub fn read_bits_fast(&mut self, n: usize) -> Result<u64> {
105        if n == 0 || n > 64 {
106            return Err(BitReadWriteError::InvalidBitCount(n).into());
107        }
108
109        while self.bits_available < n {
110            let remaining_bits = n - self.bits_available;
111            let max_bytes = (64 - self.bits_available) / 8;
112            let needed_bytes = ((remaining_bits + 7) / 8).min(max_bytes).max(1);
113
114            self.raw.read_exact(&mut self.scratch[..needed_bytes])?;
115
116            let mut val = 0u64;
117            for i in 0..needed_bytes {
118                val |= (self.scratch[i] as u64) << (i * 8);
119            }
120
121            let new_bits = needed_bytes * 8;
122            self.buffer |= val.wrapping_shl(self.bits_available as u32);
123            self.bits_available += new_bits;
124        }
125
126        let mask = if n == 64 { u64::MAX } else { (1u64 << n) - 1 };
127        let result = self.buffer & mask;
128        // 对 n==64 做特殊处理,避免溢出
129        if n < 64 {
130            self.buffer >>= n;
131        } else {
132            self.buffer = 0;
133        }
134        self.bits_available -= n;
135        Ok(result)
136    }
137}
138
139#[cfg(test)]
140mod tests {
141    use super::*;
142    use std::io::Cursor;
143
144    // ================ Big Endian 测试 ================
145    #[test]
146    fn test_big_endian_basic() {
147        let data = [0b1010_1010, 0b1100_1100];
148        let mut reader = FastBitReaderBig::new(Cursor::new(data));
149        assert_eq!(reader.read_bits_fast(4).unwrap(), 0b1010);
150        assert_eq!(reader.read_bits_fast(4).unwrap(), 0b1010);
151        assert_eq!(reader.read_bits_fast(8).unwrap(), 0b1100_1100);
152    }
153
154    #[test]
155    fn test_big_endian_cross_byte() {
156        let data = [0b1100_1100, 0b1010_1010];
157        let mut reader = FastBitReaderBig::new(Cursor::new(data));
158        assert_eq!(reader.read_bits_fast(3).unwrap(), 0b110);
159        assert_eq!(reader.read_bits_fast(10).unwrap(), 0b0_11001010_1);
160    }
161
162    #[test]
163    fn test_big_endian_large_read() {
164        let data = [0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0];
165        let mut reader = FastBitReaderBig::new(Cursor::new(data));
166        assert_eq!(reader.read_bits_fast(64).unwrap(), 0x123456789ABCDEF0);
167    }
168
169    #[test]
170    fn test_big_endian_multiple_fills() {
171        let data = [0xFF; 16];
172        let mut reader = FastBitReaderBig::new(Cursor::new(data));
173        assert_eq!(reader.read_bits_fast(56).unwrap(), 0xFFFFFFFFFFFFFF);
174        assert_eq!(reader.read_bits_fast(64).unwrap(), 0xFFFFFFFFFFFFFFFF);
175    }
176
177    // ================ Little Endian 测试 ================
178    #[test]
179    fn test_little_endian_basic() {
180        let data = [0b1010_1010, 0b1100_1100];
181        let mut reader = FastBitReaderLittle::new(Cursor::new(data));
182        assert_eq!(reader.read_bits_fast(4).unwrap(), 0b1010);
183        assert_eq!(reader.read_bits_fast(4).unwrap(), 0b1010);
184        assert_eq!(reader.read_bits_fast(8).unwrap(), 0b1100_1100);
185    }
186
187    #[test]
188    fn test_little_endian_cross_byte() {
189        let data = [0b0000_0001, 0b1000_0000];
190        let mut reader = FastBitReaderLittle::new(Cursor::new(data));
191        assert_eq!(reader.read_bits_fast(1).unwrap(), 1);
192        assert_eq!(reader.read_bits_fast(7).unwrap(), 0);
193        assert_eq!(reader.read_bits_fast(1).unwrap(), 0);
194        assert_eq!(reader.read_bits_fast(7).unwrap(), 0b1000000);
195    }
196
197    #[test]
198    fn test_little_endian_large_read() {
199        let data = [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08];
200        let mut reader = FastBitReaderLittle::new(Cursor::new(data));
201        assert_eq!(reader.read_bits_fast(64).unwrap(), 0x0807060504030201);
202    }
203
204    #[test]
205    fn test_little_endian_multiple_fills() {
206        let data = [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09];
207        let mut reader = FastBitReaderLittle::new(Cursor::new(data));
208        assert_eq!(reader.read_bits_fast(56).unwrap(), 0x07060504030201);
209        assert_eq!(reader.read_bits_fast(16).unwrap(), 0x0908);
210    }
211
212    // ================ 通用边界测试 ================
213    #[test]
214    fn test_read_past_end() {
215        let data = [0x12, 0x34];
216        let mut reader = FastBitReaderBig::new(Cursor::new(data));
217        assert_eq!(reader.read_bits_fast(16).unwrap(), 0x1234);
218        assert!(reader.read_bits_fast(1).is_err());
219    }
220
221    #[test]
222    fn test_zero_bits() {
223        let data = [0xAA];
224        let mut reader = FastBitReaderLittle::new(Cursor::new(data));
225        assert!(reader.read_bits_fast(0).is_err());
226        assert_eq!(reader.read_bits_fast(8).unwrap(), 0xAA);
227    }
228
229    #[test]
230    fn test_read_more_than_64_bits() {
231        let data = [0xFF; 16];
232        let mut reader = FastBitReaderBig::new(Cursor::new(data));
233        let result = reader.read_bits_fast(65);
234        assert!(result.is_err());
235    }
236}