Update.
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -1,5 +1,3 @@
|
||||
/target/
|
||||
|
||||
Cargo.lock
|
||||
|
||||
/.criterion/
|
||||
|
||||
@@ -4,12 +4,13 @@ version = "0.1.0"
|
||||
authors = ["logaritmisk <anders.e.olsson@gmail.com>"]
|
||||
|
||||
[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"
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ use rand::{Rng, SeedableRng, XorShiftRng};
|
||||
|
||||
use bit_set::BitSet;
|
||||
|
||||
fn default_set<C: FromIterator<u64>>(n: usize) -> C {
|
||||
fn random<C: FromIterator<u64>>(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::<Vec<_>>();
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
28
src/lib.rs
28
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<u64, Block, BitBuildHasher>;
|
||||
// type Storage = OrderMap<u64, Block, BitBuildHasher>;
|
||||
|
||||
pub type BitHashMap<V> = HashMap<u64, V, BitBuildHasher>;
|
||||
|
||||
@@ -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<u64, u64>,
|
||||
// iter: ordermap::IntoIter<u64, u64>,
|
||||
block: u64,
|
||||
bits: u64,
|
||||
bit: u64,
|
||||
|
||||
Reference in New Issue
Block a user