BitSet perf improvements

This commit makes two changes:
 1. Changes `MaybeLiveLocals` to use `ChunkedBitSet`
 2. Overrides the `fold` method for the iterator for `ChunkedBitSet`
This commit is contained in:
Jakob Degen 2022-06-05 16:22:54 -07:00
parent 02916c4c75
commit bc7cd2f351
5 changed files with 141 additions and 23 deletions

View file

@ -342,38 +342,82 @@ fn chunked_bitset() {
b10000b.assert_valid();
}
fn with_elements_chunked(elements: &[usize], domain_size: usize) -> ChunkedBitSet<usize> {
let mut s = ChunkedBitSet::new_empty(domain_size);
for &e in elements {
assert!(s.insert(e));
}
s
}
fn with_elements_standard(elements: &[usize], domain_size: usize) -> BitSet<usize> {
let mut s = BitSet::new_empty(domain_size);
for &e in elements {
assert!(s.insert(e));
}
s
}
#[test]
fn chunked_bitset_into_bitset_operations() {
let a = vec![1, 5, 7, 11, 15, 2000, 3000];
let b = vec![3, 4, 11, 3000, 4000];
let aub = vec![1, 3, 4, 5, 7, 11, 15, 2000, 3000, 4000];
let aib = vec![11, 3000];
let b = with_elements_chunked(&b, 9876);
let mut union = with_elements_standard(&a, 9876);
assert!(union.union(&b));
assert!(!union.union(&b));
assert!(union.iter().eq(aub.iter().copied()));
let mut intersection = with_elements_standard(&a, 9876);
assert!(intersection.intersect(&b));
assert!(!intersection.intersect(&b));
assert!(intersection.iter().eq(aib.iter().copied()));
}
#[test]
fn chunked_bitset_iter() {
fn with_elements(elements: &[usize], domain_size: usize) -> ChunkedBitSet<usize> {
let mut s = ChunkedBitSet::new_empty(domain_size);
for &e in elements {
s.insert(e);
fn check_iter(bit: &ChunkedBitSet<usize>, vec: &Vec<usize>) {
// Test collecting via both `.next()` and `.fold()` calls, to make sure both are correct
let mut collect_next = Vec::new();
let mut bit_iter = bit.iter();
while let Some(item) = bit_iter.next() {
collect_next.push(item);
}
s
assert_eq!(vec, &collect_next);
let collect_fold = bit.iter().fold(Vec::new(), |mut v, item| {
v.push(item);
v
});
assert_eq!(vec, &collect_fold);
}
// Empty
let vec: Vec<usize> = Vec::new();
let bit = with_elements(&vec, 9000);
assert_eq!(vec, bit.iter().collect::<Vec<_>>());
let bit = with_elements_chunked(&vec, 9000);
check_iter(&bit, &vec);
// Filled
let n = 10000;
let vec: Vec<usize> = (0..n).collect();
let bit = with_elements(&vec, n);
assert_eq!(vec, bit.iter().collect::<Vec<_>>());
let bit = with_elements_chunked(&vec, n);
check_iter(&bit, &vec);
// Filled with trailing zeros
let n = 10000;
let vec: Vec<usize> = (0..n).collect();
let bit = with_elements(&vec, 2 * n);
assert_eq!(vec, bit.iter().collect::<Vec<_>>());
let bit = with_elements_chunked(&vec, 2 * n);
check_iter(&bit, &vec);
// Mixed
let n = 12345;
let vec: Vec<usize> = vec![0, 1, 2, 2010, 2047, 2099, 6000, 6002, 6004];
let bit = with_elements(&vec, n);
assert_eq!(vec, bit.iter().collect::<Vec<_>>());
let bit = with_elements_chunked(&vec, n);
check_iter(&bit, &vec);
}
#[test]