@@ -183,42 +183,72 @@ impl Digest for Crc {
183183 }
184184}
185185
186- /// CRC32B (ISO 3309) implementation using crc_fast
186+ /// CRC32B (ISO 3309) implementation using crc_fast with SIMD optimization
187187///
188- /// Performance Note: Uses SIMD acceleration when available:
189- /// - AVX512 (>100 GiB/s) on x86_64 with AVX512 support
190- /// - SSE (~40.8ms) on x86_64 without AVX512
191- /// - NEON on ARM64
192- /// - Software fallback on other architectures
188+ /// Performance characteristics:
189+ /// - AVX512 (>100 GiB/s): x86_64 with AVX512 support
190+ /// - SSE: x86_64 without AVX512 (fallback)
191+ /// - NEON: ARM64 with NEON support
192+ /// - Software: Other architectures
193+ ///
194+ /// Note: Performance on x86_64 without AVX512 is slower than crc32fast
195+ /// due to architectural differences. This is a correctness trade-off:
196+ /// crc_fast uses ISO 3309 (correct) while crc32fast uses IEEE 802.3 (incorrect).
193197pub struct CRC32B {
194198 digest : crc_fast:: Digest ,
199+ /// Buffer for batch processing to improve cache efficiency
200+ buffer : Vec < u8 > ,
201+ }
202+
203+ impl CRC32B {
204+ /// Flush buffered data to digest
205+ fn flush_buffer ( & mut self ) {
206+ if !self . buffer . is_empty ( ) {
207+ self . digest . update ( & self . buffer ) ;
208+ self . buffer . clear ( ) ;
209+ }
210+ }
195211}
196212
197213impl Digest for CRC32B {
198214 fn new ( ) -> Self {
199215 Self {
200216 digest : crc_fast:: Digest :: new ( crc_fast:: CrcAlgorithm :: Crc32IsoHdlc ) ,
217+ buffer : Vec :: with_capacity ( 8192 ) ,
201218 }
202219 }
203220
204221 fn hash_update ( & mut self , input : & [ u8 ] ) {
205- self . digest . update ( input) ;
222+ // For small inputs, buffer them for better cache efficiency
223+ // For large inputs, flush buffer and process directly
224+ if input. len ( ) < 4096 {
225+ self . buffer . extend_from_slice ( input) ;
226+ if self . buffer . len ( ) >= 8192 {
227+ self . flush_buffer ( ) ;
228+ }
229+ } else {
230+ self . flush_buffer ( ) ;
231+ self . digest . update ( input) ;
232+ }
206233 }
207234
208235 fn hash_finalize ( & mut self , out : & mut [ u8 ] ) {
236+ self . flush_buffer ( ) ;
209237 let result = self . digest . finalize ( ) as u32 ;
210238 out. copy_from_slice ( & result. to_be_bytes ( ) ) ;
211239 }
212240
213241 fn reset ( & mut self ) {
214242 self . digest . reset ( ) ;
243+ self . buffer . clear ( ) ;
215244 }
216245
217246 fn output_bits ( & self ) -> usize {
218247 32
219248 }
220249
221250 fn result_str ( & mut self ) -> String {
251+ self . flush_buffer ( ) ;
222252 let crc_value = self . digest . finalize ( ) as u32 ;
223253 format ! ( "{crc_value}" )
224254 }
0 commit comments