Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
15 commits
Select commit Hold shift + click to select a range
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
5 changes: 5 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -111,9 +111,14 @@ harness = false
name = "product_zipper"
harness = false

[[bench]]
name = "catamorphism"
harness = false

[[bench]]
name = "sla"
harness = false
required-features = ["viz"]

[workspace]
members = ["pathmap-derive"]
Expand Down
18 changes: 17 additions & 1 deletion benches/binary_keys.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ fn binary_get(bencher: Bencher, n: u64) {
});
}

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

let keys = make_keys(n as usize, 1);
Expand All @@ -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, 100000])]
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
105 changes: 105 additions & 0 deletions benches/catamorphism.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
use divan::{Divan, Bencher, black_box};
use pathmap::morphisms::{Catamorphism, Summarization};
use pathmap::utils::ByteMask;
use pathmap::utils::ints::gen_int_range;
use pathmap::PathMap;

fn main() {
// Run registered benchmarks.
let divan = Divan::from_args()
.sample_count(4000);

divan.main();
}

fn build_map(count: u64) -> PathMap<()> {
// Dense range of u64 keys encoded as paths; sized to keep benches fast and stable.
gen_int_range::<(), 8, u64>(0, count, 1, ())
}

const MAP_COUNT: u64 = 20_000_000;

#[divan::bench()]
fn recursive_cata_jumping_val_count(bencher: Bencher) {
let map = build_map(MAP_COUNT);
let mut sink = 0usize;
bencher.bench_local(|| {
let rz = map.read_zipper();
*black_box(&mut sink) = rz.recursive_cata::<_, _, _, _, _, false>(
|v, w, _| (v.is_some() as usize) + w.unwrap_or(0),
|_mask, w: usize, total| { *total += w },
|_mask, total: usize| { total },
);
});
assert_eq!(sink, MAP_COUNT as usize);
}

#[divan::bench()]
fn cached_jumping_cata_val_count(bencher: Bencher) {
let map = build_map(MAP_COUNT);
let mut sink = 0usize;
bencher.bench_local(|| {
let rz = map.read_zipper();
*black_box(&mut sink) = rz.into_cata_jumping_cached(|_mask: &ByteMask, children: &mut [usize], val, _sub_path| {
let mut sum: usize = children.iter().sum();
if val.is_some() {
sum += 1;
}
sum
});
});
assert_eq!(sink, MAP_COUNT as usize);
}

#[divan::bench()]
fn recursive_cata_jumping_total_len(bencher: Bencher) {
let map = build_map(MAP_COUNT);
let mut sink = (0usize, 0usize);
bencher.bench_local(|| {
let rz = map.read_zipper();
*black_box(&mut sink) = rz.recursive_cata::<_, _, _, _, _, true>(
|val, downstream, prefix| {
let (mut count, mut total_len) = downstream.unwrap_or((0, 0));
total_len += count * prefix.len();
if val.is_some() {
count += 1;
total_len += prefix.len();
}
(count, total_len)
},
|mask: &ByteMask, w: (usize, usize), acc: &mut (usize, usize, usize)| {
let byte = mask.indexed_bit::<true>(acc.0).unwrap();
let _ = byte; // byte value unused; only length matters
acc.0 += 1;
acc.1 += w.0;
acc.2 += w.1;
},
|_mask: &ByteMask, acc: (usize, usize, usize)| { (acc.1, acc.2) },
);
});
assert_eq!(sink.0, MAP_COUNT as usize);
}

#[divan::bench()]
fn cached_jumping_cata_total_len(bencher: Bencher) {
let map = build_map(MAP_COUNT);
let mut sink = (0usize, 0usize);
bencher.bench_local(|| {
let rz = map.read_zipper();
*black_box(&mut sink) = rz.into_cata_jumping_cached(|mask: &ByteMask, children: &mut [(usize, usize)], val, sub_path| {
let mut count = 0usize;
let mut total_len = 0usize;
let prefix_len = sub_path.len();
if val.is_some() {
count += 1;
total_len += prefix_len;
}
for (_byte, child) in mask.iter().zip(children.iter_mut()) {
count += child.0;
total_len += child.1 + child.0 * prefix_len;
}
(count, total_len)
});
});
assert_eq!(sink.0, MAP_COUNT as usize);
}
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
Loading