@@ -14,30 +14,30 @@ impl TrieNode {
14
14
}
15
15
}
16
16
}
17
-
18
- // Bit manipulation utilities
17
+ #[ inline]
19
18
pub ( crate ) fn set_bit ( a : & mut [ u64 ; 4 ] , k : u8 ) {
20
- a[ ( k / 64 ) as usize ] |= 1u64 << ( k % 64 ) ;
19
+ a[ ( k >> 6 ) as usize ] |= 1u64 << ( k & 0x3F ) ;
21
20
}
22
-
21
+ # [ inline ]
23
22
pub ( crate ) fn clear_bit ( a : & mut [ u64 ; 4 ] , k : u8 ) {
24
- a[ ( k / 64 ) as usize ] &= !( 1u64 << ( k % 64 ) ) ;
23
+ a[ ( k >> 6 ) as usize ] &= !( 1u64 << ( k & 0x3F ) ) ;
25
24
}
26
-
25
+ # [ inline ]
27
26
pub ( crate ) fn test_bit ( a : & [ u64 ; 4 ] , k : u8 ) -> bool {
28
- ( a[ ( k / 64 ) as usize ] >> ( k % 64 ) ) & 0x01 != 0
27
+ ( a[ ( k >> 6 ) as usize ] & ( 1u64 << ( k & 0x3F ) ) ) != 0
29
28
}
30
-
29
+ # [ inline ]
31
30
pub ( crate ) fn popcount ( a : & [ u64 ; 4 ] , k : u8 ) -> u16 {
32
- let mut res = 0 ;
33
-
34
- for i in a. iter ( ) . take ( ( k / 64 ) as usize ) {
35
- res += i. count_ones ( ) as u16 ;
36
- }
37
-
38
- for i in 0 ..( k % 64 ) {
39
- res += ( ( ( a[ ( k / 64 ) as usize ] >> i) & 0x01 ) != 0 ) as u16 ;
40
- }
41
-
42
- res
31
+ // Calculate indices for full chunks and remainder
32
+ let full_chunks = ( k >> 6 ) as usize ;
33
+ let remainder_bits = k & 0x3F ;
34
+
35
+ // Use fold instead of map+sum for better performance
36
+ let full_sum: u16 = a[ ..full_chunks]
37
+ . iter ( )
38
+ . fold ( 0 , |acc, & x| acc + x. count_ones ( ) as u16 ) ;
39
+
40
+ // Add remaining bits (only if there are any)
41
+ let has_remainder = ( remainder_bits > 0 ) as u16 ;
42
+ full_sum + has_remainder * ( a[ full_chunks] & ( ( 1u64 << remainder_bits) - 1 ) ) . count_ones ( ) as u16
43
43
}
0 commit comments