Skip to content

Commit 927dd47

Browse files
[storage/index] Add insert_and_prune benchmark
Exercises the full Cursor lifecycle (next, find, delete, insert, drop) on every key, revealing the ~59% speedup from the Cursor simplification. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 3452d67 commit 927dd47

2 files changed

Lines changed: 62 additions & 0 deletions

File tree

storage/src/index/benches/bench.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ mod hashmap_insert;
99
mod hashmap_insert_fixed;
1010
mod hashmap_iteration;
1111
mod insert;
12+
mod insert_and_prune;
1213
mod lookup;
1314
mod lookup_miss;
1415

@@ -51,6 +52,7 @@ criterion_main!(
5152
hashmap_insert_fixed::benches,
5253
hashmap_insert::benches,
5354
insert::benches,
55+
insert_and_prune::benches,
5456
lookup::benches,
5557
lookup_miss::benches,
5658
);
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
use super::DummyMetrics;
2+
use commonware_cryptography::{Hasher, Sha256};
3+
use commonware_storage::{
4+
index::{unordered, Unordered},
5+
translator::FourCap,
6+
};
7+
use criterion::{criterion_group, Criterion};
8+
use rand::{rngs::StdRng, seq::SliceRandom, SeedableRng};
9+
use std::time::{Duration, Instant};
10+
11+
#[cfg(not(full_bench))]
12+
const N_ITEMS: [usize; 2] = [10_000, 50_000];
13+
#[cfg(full_bench)]
14+
const N_ITEMS: [usize; 4] = [10_000, 50_000, 100_000, 500_000];
15+
16+
fn bench_insert_and_prune(c: &mut Criterion) {
17+
for items in N_ITEMS {
18+
let mut rng = StdRng::seed_from_u64(0);
19+
let mut kvs = Vec::with_capacity(items);
20+
for i in 0..items {
21+
kvs.push((Sha256::hash(&i.to_be_bytes()), i as u64));
22+
}
23+
kvs.shuffle(&mut rng);
24+
25+
c.bench_function(&format!("{}/items={items}", module_path!()), |b| {
26+
let kvs_data = kvs.clone();
27+
b.iter_custom(move |iters| {
28+
let mut total = Duration::ZERO;
29+
for _ in 0..iters {
30+
let mut index = unordered::Index::new(DummyMetrics, FourCap);
31+
total += run_benchmark(&mut index, &kvs_data);
32+
}
33+
total
34+
});
35+
});
36+
}
37+
}
38+
39+
fn run_benchmark<I: Unordered<Value = u64>>(
40+
index: &mut I,
41+
kvs: &[(<Sha256 as Hasher>::Digest, u64)],
42+
) -> Duration {
43+
// Seed the index with initial values.
44+
for (k, v) in kvs {
45+
index.insert(k, *v);
46+
}
47+
48+
// Overwrite every key using insert_and_prune: prune the old value, insert the new one.
49+
let start = Instant::now();
50+
for (k, v) in kvs {
51+
index.insert_and_prune(k, *v + 1, |old| *old == *v);
52+
}
53+
start.elapsed()
54+
}
55+
56+
criterion_group! {
57+
name = benches;
58+
config = Criterion::default().sample_size(10);
59+
targets = bench_insert_and_prune
60+
}

0 commit comments

Comments
 (0)