Skip to content

Commit d152cbb

Browse files
committed
some optimizations
1 parent 6b89aa0 commit d152cbb

File tree

2 files changed

+23
-31
lines changed

2 files changed

+23
-31
lines changed

Diff for: src/node.rs

+19-19
Original file line numberDiff line numberDiff line change
@@ -14,30 +14,30 @@ impl TrieNode {
1414
}
1515
}
1616
}
17-
18-
// Bit manipulation utilities
17+
#[inline]
1918
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);
2120
}
22-
21+
#[inline]
2322
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));
2524
}
26-
25+
#[inline]
2726
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
2928
}
30-
29+
#[inline]
3130
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
4343
}

Diff for: src/slice_pool.rs

+4-12
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,13 @@ pub(crate) struct SlicePool {
1010
impl SlicePool {
1111
/// Creates a new empty slice pool
1212
pub fn new() -> Self {
13-
let pools = std::array::from_fn(|_| Vec::new());
13+
let pools = std::array::from_fn(|_| Vec::with_capacity(1024));
1414
SlicePool { pools }
1515
}
1616
/// Gets a boxed slice of the specified length from the pool, or creates a new one
1717
pub fn get(&mut self, len: usize) -> Box<[TrieNode]> {
18-
if len == 0 {
19-
return Box::new([]);
20-
}
2118
let idx = len.max(256);
22-
if let Some(slice) = self.pools[idx as usize].pop() {
19+
if let Some(slice) = unsafe { self.pools.get_unchecked_mut(idx as usize) }.pop() {
2320
return slice;
2421
}
2522
let mut vec = Vec::with_capacity(len as usize);
@@ -32,13 +29,8 @@ impl SlicePool {
3229
/// Returns a boxed slice to the pool for future reuse
3330
pub fn put(&mut self, slice: Box<[TrieNode]>) {
3431
let len = slice.len();
35-
36-
if len == 0 {
37-
return; // Don't pool empty slices
38-
}
39-
40-
let idx = len.min(255);
41-
self.pools[idx].push(slice);
32+
let idx = len;
33+
unsafe { self.pools.get_unchecked_mut(idx as usize) }.push(slice);
4234
}
4335

4436
/// Clears all pools, dropping all stored slices

0 commit comments

Comments
 (0)