Skip to content

Commit e195ff6

Browse files
brianpanefolkertdev
authored andcommitted
Faster comparisons for priority queue
1 parent 4ca72cd commit e195ff6

File tree

1 file changed

+16
-13
lines changed

1 file changed

+16
-13
lines changed

zlib-rs/src/deflate.rs

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2962,34 +2962,37 @@ impl Heap {
29622962
/// Index within the heap array of least frequent node in the Huffman tree
29632963
const SMALLEST: usize = 1;
29642964

2965-
fn smaller(tree: &[Value], n: u32, m: u32, depth: &[u8]) -> bool {
2966-
let (n, m) = (n as usize, m as usize);
2967-
2968-
match Ord::cmp(&tree[n].freq(), &tree[m].freq()) {
2969-
core::cmp::Ordering::Less => true,
2970-
core::cmp::Ordering::Equal => depth[n] <= depth[m],
2971-
core::cmp::Ordering::Greater => false,
2972-
}
2973-
}
2974-
29752965
fn pqdownheap(&mut self, tree: &[Value], mut k: usize) {
29762966
/* tree: the tree to restore */
29772967
/* k: node to move down */
29782968

2969+
// Given the index $i of a node in the tree, pack the node's frequency and depth
2970+
// into a single integer. The heap ordering logic uses a primary sort on frequency
2971+
// and a secondary sort on depth, so packing both into one integer makes it
2972+
// possible to sort with fewer comparison operations.
2973+
macro_rules! freq_and_depth {
2974+
($i:expr) => {
2975+
(tree[$i as usize].freq() as u32) << 8 | self.depth[$i as usize] as u32
2976+
};
2977+
}
2978+
29792979
let v = self.heap[k];
2980+
let v_val = freq_and_depth!(v);
29802981
let mut j = k << 1; /* left son of k */
29812982

29822983
while j <= self.heap_len {
29832984
/* Set j to the smallest of the two sons: */
2985+
let mut j_val = freq_and_depth!(self.heap[j]);
29842986
if j < self.heap_len {
2985-
let cond = Self::smaller(tree, self.heap[j + 1], self.heap[j], &self.depth);
2986-
if cond {
2987+
let j1_val = freq_and_depth!(self.heap[j + 1]);
2988+
if j1_val <= j_val {
29872989
j += 1;
2990+
j_val = j1_val;
29882991
}
29892992
}
29902993

29912994
/* Exit if v is smaller than both sons */
2992-
if Self::smaller(tree, v, self.heap[j], &self.depth) {
2995+
if v_val <= j_val {
29932996
break;
29942997
}
29952998

0 commit comments

Comments
 (0)