automerge/automerge-frontend/benches/statetree_apply_diff.rs
Andrew Jeffery ff8b8613d5
Flatten objtype (#175)
* Flatten object type

* Use separate construct functions

* Use separate gen_*_diff functions

* Remove maptype and seqtype from Diffs

* Preallocate ops in new_map_or_table

* More preallocations
2021-06-17 20:06:10 +01:00

133 lines
4.5 KiB
Rust

use amp::RootDiff;
use automerge_frontend::Frontend;
use automerge_protocol as amp;
use criterion::{black_box, criterion_group, criterion_main, BatchSize, Criterion};
use maplit::hashmap;
pub fn sequential_inserts_in_multiple_patches(c: &mut Criterion) {
let actor_id = amp::ActorId::random();
let make_list_opid = actor_id.op_id_at(1);
let mut patches: Vec<amp::Patch> = vec![amp::Patch {
actor: None,
seq: None,
clock: hashmap! {actor_id.clone() => 1},
deps: Vec::new(),
max_op: 1,
pending_changes: 0,
diffs: RootDiff {
props: hashmap! {
"text".to_string() => hashmap!{
make_list_opid.clone() => amp::Diff::Text(amp::TextDiff{
object_id: make_list_opid.clone().into(),
edits: Vec::new(),
}),
}
},
},
}];
for index in 0..6000 {
let op_num = index + 2;
let this_op_id = actor_id.op_id_at(op_num as u64);
patches.push(amp::Patch {
actor: None,
seq: None,
clock: hashmap! {actor_id.clone() => op_num as u64},
deps: Vec::new(),
max_op: op_num as u64,
pending_changes: 0,
diffs: RootDiff {
props: hashmap! {
"text".to_string() => hashmap!{
make_list_opid.clone() => amp::Diff::Text(amp::TextDiff{
object_id: make_list_opid.clone().into(),
edits: vec![amp::DiffEdit::SingleElementInsert{
index,
elem_id: this_op_id.clone().into(),
op_id: this_op_id.clone(),
value: amp::Diff::Value(amp::ScalarValue::Str("c".to_string())),
}],
})
}
},
},
});
}
c.bench_function(
"StateTreeValue::apply_diff sequential text inserts across multiple patches",
move |b| {
b.iter_batched(
|| {
let doc = Frontend::new();
(doc, patches.clone())
},
|(mut doc, patches)| {
#[allow(clippy::unit_arg)]
black_box({
for patch in patches.into_iter() {
doc.apply_patch(patch).unwrap();
}
doc
})
},
BatchSize::SmallInput,
)
},
);
}
pub fn sequential_inserts_in_single_patch(c: &mut Criterion) {
let actor_id = amp::ActorId::random();
let make_list_opid = actor_id.op_id_at(1);
let mut edits: Vec<amp::DiffEdit> = Vec::new();
for index in 0..6000 {
let op_num = index + 2;
let this_op_id = actor_id.op_id_at(op_num as u64);
edits.push(amp::DiffEdit::SingleElementInsert {
index,
elem_id: this_op_id.clone().into(),
op_id: this_op_id.clone(),
value: amp::Diff::Value(amp::ScalarValue::Str("c".to_string())),
});
}
let patch: amp::Patch = amp::Patch {
actor: None,
seq: None,
clock: hashmap! {actor_id => 1},
deps: Vec::new(),
max_op: 1,
pending_changes: 0,
diffs: RootDiff {
props: hashmap! {
"text".to_string() => hashmap!{
make_list_opid.clone() => amp::Diff::Text(amp::TextDiff{
object_id: make_list_opid.into(),
edits,
}),
}
},
},
};
c.bench_function(
"StateTreeValue::apply_diff sequential text inserts in a single patch",
move |b| {
b.iter_batched(
|| patch.clone(),
|patch| {
#[allow(clippy::unit_arg)]
black_box({
let mut doc = Frontend::new();
doc.apply_patch(patch).unwrap()
})
},
BatchSize::SmallInput,
)
},
);
}
criterion_group! {
name = benches;
config = Criterion::default().sample_size(10);
targets = sequential_inserts_in_multiple_patches, sequential_inserts_in_single_patch,
}
criterion_main!(benches);