@@ -201,6 +201,28 @@ pub fn apply_bitwise_binary_op<F>(
201201 return ;
202202 }
203203
204+ // Special case word aligned buffers and use u64 operations
205+ if left_offset_in_bits == 0 && right_offset_in_bits == 0 {
206+ unsafe {
207+ let ( left_prefix, left_u64s, left_suffix) = left. align_to_mut :: < u64 > ( ) ;
208+ let ( right_prefix, right_u64s, right_suffix) = right. as_ref ( ) . align_to :: < u64 > ( ) ;
209+ // if there is no prefix or suffix, both buffers are aligned and we can do the operation directly
210+ // on u64s
211+ // TODO also handle non empty suffixes by processing them separately
212+ if left_prefix. is_empty ( )
213+ && right_prefix. is_empty ( )
214+ && left_suffix. is_empty ( )
215+ && right_suffix. is_empty ( )
216+ {
217+ left_u64s
218+ . iter_mut ( )
219+ . zip ( right_u64s. iter ( ) )
220+ . for_each ( |( l, r) | * l = op ( * l, * r) ) ;
221+ return ;
222+ }
223+ }
224+ }
225+
204226 // offset inside a byte
205227 let bit_offset = left_offset_in_bits % 8 ;
206228
@@ -308,6 +330,20 @@ pub fn apply_bitwise_unary_op<F>(
308330 return ;
309331 }
310332
333+ // Special case word aligned buffers and use u64 operations
334+ if offset_in_bits == 0 {
335+ unsafe {
336+ let ( prefix, mut u64s, suffix) = buffer. align_to_mut :: < u64 > ( ) ;
337+ // if there is no prefix or suffix, both buffers are aligned and we can do the operation directly
338+ // on u64s
339+ // TODO also handle non empty suffixes by processing them separately
340+ if prefix. is_empty ( ) && suffix. is_empty ( ) {
341+ u64s. iter_mut ( ) . for_each ( |v| * v = op ( * v) ) ;
342+ return ;
343+ }
344+ }
345+ }
346+
311347 // offset inside a byte
312348 let left_bit_offset = offset_in_bits % 8 ;
313349
0 commit comments