Update.
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -1,5 +1,3 @@
|
|||||||
/target/
|
/target/
|
||||||
|
|
||||||
Cargo.lock
|
Cargo.lock
|
||||||
|
|
||||||
/.criterion/
|
|
||||||
|
|||||||
@@ -4,12 +4,13 @@ version = "0.1.0"
|
|||||||
authors = ["logaritmisk <anders.e.olsson@gmail.com>"]
|
authors = ["logaritmisk <anders.e.olsson@gmail.com>"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
ordermap = "0.4"
|
||||||
rayon = "0.9"
|
rayon = "0.9"
|
||||||
serde = "1.0"
|
serde = "1.0"
|
||||||
unreachable = "1.0"
|
unreachable = "1.0"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
criterion = "0.1"
|
criterion = "0.2"
|
||||||
rand = "0.4"
|
rand = "0.4"
|
||||||
serde_test = "1.0"
|
serde_test = "1.0"
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ use rand::{Rng, SeedableRng, XorShiftRng};
|
|||||||
|
|
||||||
use bit_set::BitSet;
|
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]);
|
let mut rng = XorShiftRng::from_seed([0, 1, 2, 3]);
|
||||||
|
|
||||||
(0..n).map(|_| rng.next_u64()).collect()
|
(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;
|
a - b;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn criterion_benchmark(c: &mut Criterion) {
|
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("contains", move |b| {
|
||||||
c.bench_function("insert", |b| b.iter(|| insert(&data)));
|
let data: Vec<_> = random(10_000);
|
||||||
|
|
||||||
let lhs: BitSet = default_set(1000);
|
b.iter(|| contains(&data));
|
||||||
let rhs: BitSet = default_set(1000);
|
});
|
||||||
|
|
||||||
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);
|
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 rayon;
|
||||||
extern crate serde;
|
extern crate serde;
|
||||||
extern crate unreachable;
|
extern crate unreachable;
|
||||||
@@ -8,6 +9,7 @@ use std::iter::{FromIterator, IntoIterator, Iterator};
|
|||||||
use std::default::Default;
|
use std::default::Default;
|
||||||
use std::collections::{HashMap, LinkedList};
|
use std::collections::{HashMap, LinkedList};
|
||||||
|
|
||||||
|
use ordermap::OrderMap;
|
||||||
use rayon::iter::{FromParallelIterator, IntoParallelIterator, ParallelExtend, ParallelIterator};
|
use rayon::iter::{FromParallelIterator, IntoParallelIterator, ParallelExtend, ParallelIterator};
|
||||||
|
|
||||||
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||||
@@ -22,6 +24,7 @@ const BITS: u64 = 64;
|
|||||||
|
|
||||||
type Block = u64;
|
type Block = u64;
|
||||||
type Storage = HashMap<u64, Block, BitBuildHasher>;
|
type Storage = HashMap<u64, Block, BitBuildHasher>;
|
||||||
|
// type Storage = OrderMap<u64, Block, BitBuildHasher>;
|
||||||
|
|
||||||
pub type BitHashMap<V> = HashMap<u64, V, BitBuildHasher>;
|
pub type BitHashMap<V> = HashMap<u64, V, BitBuildHasher>;
|
||||||
|
|
||||||
@@ -64,7 +67,7 @@ impl BitSet {
|
|||||||
|
|
||||||
pub fn shrink_to_fit(&mut self) {
|
pub fn shrink_to_fit(&mut self) {
|
||||||
self.blocks.retain(|_, block| *block != 0);
|
self.blocks.retain(|_, block| *block != 0);
|
||||||
self.blocks.shrink_to_fit()
|
// self.blocks.shrink_to_fit();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn iter(&self) -> Iter {
|
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 {
|
impl<'a> ops::Sub<&'a BitSet> for &'a BitSet {
|
||||||
type Output = BitSet;
|
type Output = BitSet;
|
||||||
|
|
||||||
@@ -269,6 +293,7 @@ impl<'a> ops::Sub<&'a BitSet> for &'a BitSet {
|
|||||||
|
|
||||||
pub struct Iter<'a> {
|
pub struct Iter<'a> {
|
||||||
iter: std::collections::hash_map::Iter<'a, u64, u64>,
|
iter: std::collections::hash_map::Iter<'a, u64, u64>,
|
||||||
|
// iter: ordermap::Iter<'a, u64, u64>,
|
||||||
block: u64,
|
block: u64,
|
||||||
bits: u64,
|
bits: u64,
|
||||||
bit: u64,
|
bit: u64,
|
||||||
@@ -276,6 +301,7 @@ pub struct Iter<'a> {
|
|||||||
|
|
||||||
pub struct IntoIter {
|
pub struct IntoIter {
|
||||||
iter: std::collections::hash_map::IntoIter<u64, u64>,
|
iter: std::collections::hash_map::IntoIter<u64, u64>,
|
||||||
|
// iter: ordermap::IntoIter<u64, u64>,
|
||||||
block: u64,
|
block: u64,
|
||||||
bits: u64,
|
bits: u64,
|
||||||
bit: u64,
|
bit: u64,
|
||||||
|
|||||||
Reference in New Issue
Block a user