From a62326cdb3fef82d9c9d454ee7b8ee829f109898 Mon Sep 17 00:00:00 2001 From: logaritmisk Date: Tue, 6 Feb 2018 11:16:42 +0100 Subject: [PATCH] Update. --- .gitignore | 2 -- Cargo.toml | 3 +- benches/bench.rs | 73 ++++++++++++++++++++++++++++++++++++++++++------ src/lib.rs | 28 ++++++++++++++++++- 4 files changed, 94 insertions(+), 12 deletions(-) diff --git a/.gitignore b/.gitignore index 5ca769f..e13de17 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,3 @@ /target/ Cargo.lock - -/.criterion/ diff --git a/Cargo.toml b/Cargo.toml index d052ac5..ee62665 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,12 +4,13 @@ version = "0.1.0" authors = ["logaritmisk "] [dependencies] +ordermap = "0.4" rayon = "0.9" serde = "1.0" unreachable = "1.0" [dev-dependencies] -criterion = "0.1" +criterion = "0.2" rand = "0.4" serde_test = "1.0" diff --git a/benches/bench.rs b/benches/bench.rs index dbddcfe..a95aca3 100644 --- a/benches/bench.rs +++ b/benches/bench.rs @@ -11,7 +11,7 @@ use rand::{Rng, SeedableRng, XorShiftRng}; use bit_set::BitSet; -fn default_set>(n: usize) -> C { +fn random>(n: usize) -> C { let mut rng = XorShiftRng::from_seed([0, 1, 2, 3]); (0..n).map(|_| rng.next_u64()).collect() @@ -33,20 +33,77 @@ fn insert(data: &[u64]) { } } -fn sub(a: &BitSet, b: &BitSet) { +fn iter(set: &BitSet) { + set.iter().collect::>(); +} + +fn is_subset(a: &BitSet, b: &BitSet) { + a.is_subset(b); +} + +fn ops_bit_or(a: &BitSet, b: &BitSet) { + a | b; +} + +fn ops_sub(a: &BitSet, b: &BitSet) { a - b; } fn criterion_benchmark(c: &mut Criterion) { - let data: Vec<_> = default_set(1000); + // c.sample_size(200); - c.bench_function("contains", |b| b.iter(|| contains(&data))); - c.bench_function("insert", |b| b.iter(|| insert(&data))); + c.bench_function("contains", move |b| { + let data: Vec<_> = random(10_000); - let lhs: BitSet = default_set(1000); - let rhs: BitSet = default_set(1000); + b.iter(|| contains(&data)); + }); - c.bench_function("sub", |b| b.iter(|| sub(&lhs, &rhs))); + c.bench_function("insert", move |b| { + let data: Vec<_> = random(10_000); + + b.iter(|| insert(&data)); + }); + + c.bench_function("iter", move |b| { + let set: BitSet = random(10_000); + + b.iter(|| iter(&set)); + }); + + c.bench_function("is_subset (>)", |b| { + let lhs: BitSet = random(10_000); + let rhs: BitSet = random(5_000); + + b.iter(|| is_subset(&lhs, &rhs)); + }); + + c.bench_function("is_subset (<)", |b| { + let lhs: BitSet = random(5_000); + let rhs: BitSet = random(10_000); + + b.iter(|| is_subset(&lhs, &rhs)); + }); + + c.bench_function("is_subset (=)", |b| { + let lhs: BitSet = random(10_000); + let rhs: BitSet = random(10_000); + + b.iter(|| is_subset(&lhs, &rhs)); + }); + + c.bench_function("ops_bit_or", move |b| { + let lhs: BitSet = random(10_000); + let rhs: BitSet = random(10_000); + + b.iter(|| ops_bit_or(&lhs, &rhs)); + }); + + c.bench_function("ops_sub", move |b| { + let lhs: BitSet = random(10_000); + let rhs: BitSet = random(10_000); + + b.iter(|| ops_sub(&lhs, &rhs)); + }); } criterion_group!(benches, criterion_benchmark); diff --git a/src/lib.rs b/src/lib.rs index ae962d8..70a6884 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,3 +1,4 @@ +extern crate ordermap; extern crate rayon; extern crate serde; extern crate unreachable; @@ -8,6 +9,7 @@ use std::iter::{FromIterator, IntoIterator, Iterator}; use std::default::Default; use std::collections::{HashMap, LinkedList}; +use ordermap::OrderMap; use rayon::iter::{FromParallelIterator, IntoParallelIterator, ParallelExtend, ParallelIterator}; use serde::{Deserialize, Deserializer, Serialize, Serializer}; @@ -22,6 +24,7 @@ const BITS: u64 = 64; type Block = u64; type Storage = HashMap; +// type Storage = OrderMap; pub type BitHashMap = HashMap; @@ -64,7 +67,7 @@ impl BitSet { pub fn shrink_to_fit(&mut self) { self.blocks.retain(|_, block| *block != 0); - self.blocks.shrink_to_fit() + // self.blocks.shrink_to_fit(); } pub fn iter(&self) -> Iter { @@ -246,6 +249,27 @@ impl<'a> ops::BitOr<&'a Self> for BitSet { } } +impl<'a> ops::BitOr<&'a BitSet> for &'a BitSet { + type Output = BitSet; + + #[inline] + fn bitor(self, rhs: &'a BitSet) -> BitSet { + let mut set = self.clone(); + + for (key, value) in &rhs.blocks { + let block = set.blocks.entry(*key).or_insert(0); + + let n = block.count_ones(); + + *block |= value; + + set.nbits += (block.count_ones() - n) as usize; + } + + set + } +} + impl<'a> ops::Sub<&'a BitSet> for &'a BitSet { type Output = BitSet; @@ -269,6 +293,7 @@ impl<'a> ops::Sub<&'a BitSet> for &'a BitSet { pub struct Iter<'a> { iter: std::collections::hash_map::Iter<'a, u64, u64>, + // iter: ordermap::Iter<'a, u64, u64>, block: u64, bits: u64, bit: u64, @@ -276,6 +301,7 @@ pub struct Iter<'a> { pub struct IntoIter { iter: std::collections::hash_map::IntoIter, + // iter: ordermap::IntoIter, block: u64, bits: u64, bit: u64,