Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ harness = false
[[bench]]
name = "sla"
harness = false
required-features = ["viz"]

[workspace]
members = ["pathmap-derive"]
Expand Down
16 changes: 16 additions & 0 deletions benches/binary_keys.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,22 @@ fn binary_val_count_bench(bencher: Bencher, n: u64) {
assert_eq!(sink, n as usize);
}

#[divan::bench(args = [125, 250, 500, 1000, 2000, 4000])]
fn binary_goat_val_count_bench(bencher: Bencher, n: u64) {

let keys = make_keys(n as usize, 1);

let mut map: PathMap<u64> = PathMap::new();
for i in 0..n { map.set_val_at(&keys[i as usize], i); }

//Benchmark the time taken to count the number of values in the map
let mut sink = 0;
bencher.bench_local(|| {
*black_box(&mut sink) = map.goat_val_count()
});
assert_eq!(sink, n as usize);
}

#[divan::bench(args = [50, 100, 200, 400, 800, 1600])]
fn binary_drop_head(bencher: Bencher, n: u64) {

Expand Down
19 changes: 19 additions & 0 deletions benches/cities.rs
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,25 @@ fn cities_val_count(bencher: Bencher) {
assert_eq!(sink, unique_count);
}

#[divan::bench()]
fn cities_goat_val_count(bencher: Bencher) {

let pairs = read_data();
let mut map = PathMap::new();
let mut unique_count = 0;
for (k, v) in pairs.iter() {
if map.set_val_at(k, *v).is_none() {
unique_count += 1;
}
}

let mut sink = 0;
bencher.bench_local(|| {
*black_box(&mut sink) = map.goat_val_count();
});
assert_eq!(sink, unique_count);
}

#[cfg(feature="arena_compact")]
#[divan::bench()]
fn cities_val_count_act(bencher: Bencher) {
Expand Down
38 changes: 38 additions & 0 deletions benches/shakespeare.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,25 @@ fn shakespeare_words_val_count(bencher: Bencher) {
assert_eq!(sink, unique_count);
}

#[divan::bench()]
fn shakespeare_words_goat_val_count(bencher: Bencher) {

let strings = read_data(true);
let mut map = PathMap::new();
let mut unique_count = 0;
for (v, k) in strings.iter().enumerate() {
if map.set_val_at(k, v).is_none() {
unique_count += 1;
}
}

let mut sink = 0;
bencher.bench_local(|| {
*black_box(&mut sink) = map.goat_val_count();
});
assert_eq!(sink, unique_count);
}

#[divan::bench()]
fn shakespeare_sentences_insert(bencher: Bencher) {

Expand Down Expand Up @@ -168,6 +187,25 @@ fn shakespeare_sentences_val_count(bencher: Bencher) {
assert_eq!(sink, unique_count);
}

#[divan::bench()]
fn shakespeare_sentences_goat_val_count(bencher: Bencher) {

let strings = read_data(false);
let mut map = PathMap::new();
let mut unique_count = 0;
for (v, k) in strings.iter().enumerate() {
if map.set_val_at(k, v).is_none() {
unique_count += 1;
}
}

let mut sink = 0;
bencher.bench_local(|| {
*black_box(&mut sink) = map.goat_val_count();
});
assert_eq!(sink, unique_count);
}

#[cfg(feature="arena_compact")]
#[divan::bench()]
fn shakespeare_sentences_val_count_act(bencher: Bencher) {
Expand Down
2 changes: 1 addition & 1 deletion benches/sla.rs
Original file line number Diff line number Diff line change
Expand Up @@ -388,7 +388,7 @@ fn tipover_attention_weave() {
// let res = rtq.vF_mut().merkleize();
// println!("{:?}", res.hash);
let t0 = Instant::now();
println!("{:?} {:?}", rtq.vF().read_zipper().into_cata_cached(morphisms::alg::hash), t0.elapsed().as_micros());
// println!("{:?} {:?}", rtq.vF().read_zipper().into_cata_cached(morphisms::alg::hash), t0.elapsed().as_micros());
return;

// rtk.vF_mut().merkleize();
Expand Down
20 changes: 20 additions & 0 deletions benches/sparse_keys.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,26 @@ fn sparse_val_count_bench(bencher: Bencher, n: u64) {
assert_eq!(sink, n as usize);
}

#[divan::bench(args = [125, 250, 500, 1000, 2000, 4000])]
fn sparse_goat_val_count_bench(bencher: Bencher, n: u64) {

let mut r = StdRng::seed_from_u64(1);
let keys: Vec<Vec<u8>> = (0..n).into_iter().map(|_| {
let len = (r.random::<u8>() % 18) + 3; //length between 3 and 20 chars
(0..len).into_iter().map(|_| r.random::<u8>()).collect()
}).collect();

let mut map: PathMap<u64> = PathMap::new();
for i in 0..n { map.set_val_at(&keys[i as usize], i); }

//Benchmark the time taken to count the number of values in the map
let mut sink = 0;
bencher.bench_local(|| {
*black_box(&mut sink) = map.goat_val_count()
});
assert_eq!(sink, n as usize);
}

#[divan::bench(args = [50, 100, 200, 400, 800, 1600])]
fn binary_drop_head(bencher: Bencher, n: u64) {

Expand Down
15 changes: 15 additions & 0 deletions benches/superdense_keys.rs
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,21 @@ fn superdense_val_count_bench(bencher: Bencher, n: u64) {
assert_eq!(sink, n as usize);
}

#[divan::bench(sample_size = 1, args = [100, 200, 400, 800, 1600, 3200, 20_000])]
fn superdense_goat_val_count_bench(bencher: Bencher, n: u64) {

let mut map: PathMap<u64> = PathMap::new();
for i in 0..n { map.set_val_at(prefix_key(&i), i); }

//Benchmark the time taken to count the number of values in the map
let mut sink = 0;
bencher.bench_local(|| {
*black_box(&mut sink) = map.goat_val_count()
});
assert_eq!(sink, n as usize);
}


#[cfg(feature="arena_compact")]
#[divan::bench(sample_size = 1, args = [100, 200, 400, 800, 1600, 3200, 20_000])]
fn superdense_val_count_bench_act(bencher: Bencher, n: u64) {
Expand Down
14 changes: 11 additions & 3 deletions src/dense_byte_node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ pub struct ByteNode<Cf, A: Allocator> {
#[cfg(feature = "nightly")]
values: Vec<Cf, A>,
#[cfg(not(feature = "nightly"))]
values: Vec<Cf>,
pub(crate) values: Vec<Cf>,
alloc: A,
}

Expand Down Expand Up @@ -991,10 +991,18 @@ impl<V: Clone + Send + Sync, A: Allocator, Cf: CoFree<V=V, A=A>> TrieNode<V, A>
t + cf.has_val() as usize + cf.rec().map(|r| val_count_below_node(r, cache)).unwrap_or(0)
});
}
fn node_goat_val_count(&self) -> usize {
/* fn node_goat_val_count(&self) -> usize {
return self.values.iter().rfold(0, |t, cf| {
t + cf.has_val() as usize
t + cf.has_val() as usize + cf.rec().map(|r| r.as_tagged().node_goat_val_count()).unwrap_or(0)
});
}*/
#[inline]
fn node_goat_val_count(&self) -> usize {
let mut result = 0;
for cf in self.values.iter() {
result += cf.has_val() as usize
}
result
}
fn node_child_iter_start(&self) -> (u64, Option<&TrieNodeODRc<V, A>>) {
for (pos, cf) in self.values.iter().enumerate() {
Expand Down
23 changes: 21 additions & 2 deletions src/line_list_node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -403,7 +403,7 @@ impl<V: Clone + Send + Sync, A: Allocator> LineListNode<V, A> {
}
}
#[inline]
unsafe fn child_in_slot<const SLOT: usize>(&self) -> &TrieNodeODRc<V, A> {
pub(crate) unsafe fn child_in_slot<const SLOT: usize>(&self) -> &TrieNodeODRc<V, A> {
match SLOT {
0 => unsafe{ &*self.val_or_child0.child },
1 => unsafe{ &*self.val_or_child1.child },
Expand All @@ -419,7 +419,7 @@ impl<V: Clone + Send + Sync, A: Allocator> LineListNode<V, A> {
}
}
#[inline]
unsafe fn val_in_slot<const SLOT: usize>(&self) -> &V {
pub(crate) unsafe fn val_in_slot<const SLOT: usize>(&self) -> &V {
match SLOT {
0 => unsafe{ &**self.val_or_child0.val },
1 => unsafe{ &**self.val_or_child1.val },
Expand Down Expand Up @@ -1986,6 +1986,25 @@ impl<V: Clone + Send + Sync, A: Allocator> TrieNode<V, A> for LineListNode<V, A>
}
result
}
/* #[inline]
fn node_goat_val_count(&self) -> usize {
let mut result = 0;
if self.is_used_value_0() {
result += 1;
}
if self.is_used_value_1() {
result += 1;
}
if self.is_used_child_0() {
let child_node = unsafe{ self.child_in_slot::<0>() };
result += child_node.as_tagged().node_goat_val_count();
}
if self.is_used_child_1() {
let child_node = unsafe{ self.child_in_slot::<1>() };
result += child_node.as_tagged().node_goat_val_count();
}
result
}*/
#[inline]
fn node_goat_val_count(&self) -> usize {
//Here are 3 alternative implementations. They're basically the same in perf, with a slight edge to the
Expand Down
22 changes: 19 additions & 3 deletions src/trie_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -511,9 +511,25 @@ impl<V: Clone + Send + Sync + Unpin, A: Allocator> PathMap<V, A> {
let root_val = unsafe{ &*self.root_val.get() }.is_some() as usize;
match self.root() {
Some(root) => {
traverse_physical(root,
|node, ctx: usize| { ctx + node.node_goat_val_count() },
|ctx, child_ctx| { ctx + child_ctx },
// root.as_tagged().node_goat_val_count() + root_val
// traverse_physical(root,
// |node, ctx: usize| { ctx + node.node_goat_val_count() },
// |ctx, child_ctx| { ctx + child_ctx },
// ) + root_val

// traverse_split_cata(
// root,
// |v, _| { 1usize },
// |_, w, _| { 1 + w },
// |bm, ws: &mut [usize], _| { ws.iter().sum() }
// ) + root_val
// Adam: this doesn't need to be called "traverse_osplit_cata" or be exposed under this interface; it can just live in morphisms
traverse_osplit_cata(
root,
|v, _| { 1usize }, // on leaf values
|_, w, _| { 1 + w }, // on values amongst a path
|bm, w: usize, _, total| { *total += w }, // on merging children into a node
|bm, total: usize, _| { total } // finalizing a node
) + root_val
},
None => root_val
Expand Down
Loading