|
80 | 80 | // if there is no prefix or suffix, both buffers are aligned and we can do the operation directly |
81 | 81 | // on u64s |
82 | 82 | // TODO also handle non empty suffixes by processing them separately |
83 | | - if left_prefix.is_empty() && right_prefix.is_empty() && left_suffix.is_empty() && right_suffix.is_empty() { |
| 83 | + if left_prefix.is_empty() |
| 84 | + && right_prefix.is_empty() |
| 85 | + && left_suffix.is_empty() |
| 86 | + && right_suffix.is_empty() |
| 87 | + { |
84 | 88 | let result_u64s = left_u64s |
85 | 89 | .iter() |
86 | 90 | .zip(right_u64s.iter()) |
|
91 | 95 | } |
92 | 96 | } |
93 | 97 |
|
94 | | - |
95 | | - |
96 | 98 | let left_chunks = left.bit_chunks(left_offset_in_bits, len_in_bits); |
97 | 99 | let right_chunks = right.bit_chunks(right_offset_in_bits, len_in_bits); |
98 | 100 |
|
@@ -124,6 +126,21 @@ pub fn bitwise_unary_op_helper<F>( |
124 | 126 | where |
125 | 127 | F: FnMut(u64) -> u64, |
126 | 128 | { |
| 129 | + // If the underlying buffer is aligned to u64, apply the operation directly on the u64 slices |
| 130 | + // to improve performance. |
| 131 | + if offset_in_bits == 0 && len_in_bits > 0 { |
| 132 | + unsafe { |
| 133 | + let (prefix, u64s, suffix) = left.as_slice().align_to::<u64>(); |
| 134 | + // if there is no prefix or suffix, the buffer is aligned and we can do the operation directly |
| 135 | + // on u64s |
| 136 | + // TODO also handle non empty suffixes by processing them separately |
| 137 | + if prefix.is_empty() && suffix.is_empty() { |
| 138 | + let result_u64s = u64s.iter().map(|l| op(*l)).collect::<Vec<u64>>(); |
| 139 | + return result_u64s.into(); |
| 140 | + } |
| 141 | + } |
| 142 | + } |
| 143 | + |
127 | 144 | // reserve capacity and set length so we can get a typed view of u64 chunks |
128 | 145 | let mut result = |
129 | 146 | MutableBuffer::new(ceil(len_in_bits, 8)).with_bitset(len_in_bits / 64 * 8, false); |
|
0 commit comments