automerge/rust/automerge/benches/sync.rs
Alex Good dd3c6d1303
Move rust workspace into ./rust
After some discussion with PVH I realise that the repo structure in the
last reorg was very rust-centric. In an attempt to put each language on
a level footing move the rust code and project files into ./rust
2022-10-16 19:55:51 +01:00

91 lines
2.6 KiB
Rust

use automerge::{sync, transaction::Transactable, Automerge, ROOT};
use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion};
#[derive(Default)]
struct DocWithSync {
doc: Automerge,
peer_state: sync::State,
}
impl From<Automerge> for DocWithSync {
fn from(doc: Automerge) -> Self {
Self {
doc,
peer_state: sync::State::default(),
}
}
}
fn increasing_put(n: u64) -> Automerge {
let mut doc = Automerge::new();
let mut tx = doc.transaction();
for i in 0..n {
tx.put(ROOT, i.to_string(), i).unwrap();
}
tx.commit();
doc
}
// keep syncing until doc1 no longer generates a sync message for doc2.
fn sync(doc1: &mut DocWithSync, doc2: &mut DocWithSync) {
while let Some(message1) = doc1.doc.generate_sync_message(&mut doc1.peer_state) {
doc2.doc
.receive_sync_message(&mut doc2.peer_state, message1)
.unwrap();
if let Some(message2) = doc2.doc.generate_sync_message(&mut doc2.peer_state) {
doc1.doc
.receive_sync_message(&mut doc1.peer_state, message2)
.unwrap()
}
}
}
fn criterion_benchmark(c: &mut Criterion) {
let sizes = [100, 1_000, 10_000];
let mut group = c.benchmark_group("sync unidirectional");
for size in &sizes {
group.throughput(criterion::Throughput::Elements(*size));
group.bench_with_input(
BenchmarkId::new("increasing put", size),
size,
|b, &size| {
b.iter_batched(
|| (increasing_put(size), DocWithSync::default()),
|(doc1, mut doc2)| sync(&mut doc1.into(), &mut doc2),
criterion::BatchSize::LargeInput,
)
},
);
}
group.finish();
let mut group = c.benchmark_group("sync unidirectional every change");
for size in &sizes {
group.throughput(criterion::Throughput::Elements(*size));
group.bench_with_input(
BenchmarkId::new("increasing put", size),
size,
|b, &size| {
b.iter(|| {
let mut doc1 = DocWithSync::default();
let mut doc2 = DocWithSync::default();
for i in 0..size {
let mut tx = doc1.doc.transaction();
tx.put(ROOT, i.to_string(), i).unwrap();
tx.commit();
sync(&mut doc1, &mut doc2);
}
})
},
);
}
group.finish();
}
criterion_group!(benches, criterion_benchmark);
criterion_main!(benches);