From ae6e292c9d036d0f487a5aeefe4d7bed04ca5f40 Mon Sep 17 00:00:00 2001 From: logaritmisk Date: Fri, 12 Jan 2018 18:17:59 +0100 Subject: [PATCH] Small performance boost. --- Cargo.toml | 3 +++ benches/bench.rs | 25 ++++++++++++++++++------- src/lib.rs | 46 ++++++++++++++++++++++++++++------------------ 3 files changed, 49 insertions(+), 25 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index ca4f5da..f8447be 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,5 +17,8 @@ serde_test = "1.0" name = "bench" harness = false +[lib] +bench = false + [profile.release] lto = true diff --git a/benches/bench.rs b/benches/bench.rs index 1d70994..1815816 100644 --- a/benches/bench.rs +++ b/benches/bench.rs @@ -17,16 +17,27 @@ fn default_set>(n: usize) -> C { (0..n).map(|_| rng.next_u64()).collect() } +fn contains(data: &[u64]) { + let set = BitSet::new(); + + for v in data { + set.contains(v); + } +} + +fn insert(data: &[u64]) { + let mut set = BitSet::new(); + + for v in data { + set.insert(*v); + } +} + fn criterion_benchmark(c: &mut Criterion) { let data: Vec<_> = default_set(1000); - c.bench_function("insert", |b| b.iter(|| { - let mut set = BitSet::new(); - - for v in &data { - set.insert(*v); - } - })); + c.bench_function("contains", |b| b.iter(|| contains(&data))); + c.bench_function("insert", |b| b.iter(|| insert(&data))); } criterion_group!(benches, criterion_benchmark); diff --git a/src/lib.rs b/src/lib.rs index d676754..a98186e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -76,10 +76,12 @@ impl BitSet { } } + #[inline] pub fn len(&self) -> usize { self.nbits } + #[inline] pub fn is_empty(&self) -> bool { self.nbits == 0 } @@ -89,6 +91,7 @@ impl BitSet { self.nbits = 0; } + #[inline] pub fn contains(&self, value: &u64) -> bool { let (block, bit) = block_bit(value, &BITS); @@ -98,6 +101,7 @@ impl BitSet { } } + #[inline] pub fn is_subset(&self, other: &BitSet) -> bool { if self.nbits > other.nbits { false @@ -116,6 +120,7 @@ impl BitSet { other.is_subset(self) } + #[inline] pub fn insert(&mut self, value: u64) -> bool { let (block, bit) = block_bit(&value, &BITS); let block = self.blocks.entry(block).or_insert(0); @@ -132,6 +137,7 @@ impl BitSet { } } + #[inline] pub fn remove(&mut self, value: &u64) -> bool { let (block, bit) = block_bit(value, &BITS); let block = self.blocks.entry(block).or_insert(0); @@ -148,15 +154,17 @@ impl BitSet { } } + #[inline] pub fn union_with(&mut self, other: &Self) { for (key, value) in &other.blocks { - *self.blocks.entry(*key).or_insert(0) |= value; - } + let block = self.blocks.entry(*key).or_insert(0); - self.nbits = self.blocks - .values() - .map(|block| block.count_ones() as usize) - .sum(); + let n = block.count_ones(); + + *block |= value; + + self.nbits += (block.count_ones() - n) as usize; + } } } @@ -206,13 +214,14 @@ impl ops::BitOr for BitSet { #[inline] fn bitor(mut self, rhs: Self) -> Self { for (key, value) in &rhs.blocks { - *self.blocks.entry(*key).or_insert(0) |= value; - } + let block = self.blocks.entry(*key).or_insert(0); - self.nbits = self.blocks - .values() - .map(|block| block.count_ones() as usize) - .sum(); + let n = block.count_ones(); + + *block |= value; + + self.nbits += (block.count_ones() - n) as usize; + } self } @@ -224,13 +233,14 @@ impl<'a> ops::BitOr<&'a Self> for BitSet { #[inline] fn bitor(mut self, rhs: &'a Self) -> Self { for (key, value) in &rhs.blocks { - *self.blocks.entry(*key).or_insert(0) |= value; - } + let block = self.blocks.entry(*key).or_insert(0); - self.nbits = self.blocks - .values() - .map(|block| block.count_ones() as usize) - .sum(); + let n = block.count_ones(); + + *block |= value; + + self.nbits += (block.count_ones() - n) as usize; + } self }