loro/crates/loro-internal/benches/tree.rs
Zixuan Chen 09a004e365
refactor: Loro import function should return LoroEncodeError (#487)
* refactor: Loro import function should return LoroEncodeError

- Change return type
- Add support for handling potential errors:
  - Invalid or non-existent frontiers
  - Exporting old snapshot format from trimmed snapshot doc
- Improve compatibility with trimmed docs

* fix: add tests and fix a few places that need to return err
2024-10-02 11:11:08 +08:00

152 lines
5.7 KiB
Rust

use criterion::{criterion_group, criterion_main, Criterion};
mod tree {
use super::*;
use criterion::{AxisScale, BenchmarkId, PlotConfiguration};
use loro_internal::{LoroDoc, TreeParentId};
use rand::{rngs::StdRng, Rng};
pub fn tree_move(c: &mut Criterion) {
let mut group = c.benchmark_group("movable tree");
let plot_config = PlotConfiguration::default().summary_scale(AxisScale::Logarithmic);
group.plot_config(plot_config);
group.sample_size(10);
for i in 3..=6 {
let input = 10u64.pow(i);
group.bench_with_input(
BenchmarkId::new("create node append", input),
&input,
|b, i| {
b.iter(|| {
let loro = LoroDoc::new_auto_commit();
let tree = loro.get_tree("tree");
for idx in 0..*i {
tree.create_at(TreeParentId::Root, idx as usize).unwrap();
}
})
},
);
group.bench_with_input(
BenchmarkId::new("move node append", input),
&input,
|b, i| {
let loro = LoroDoc::new_auto_commit();
let tree = loro.get_tree("tree");
const SIZE: usize = 1000;
let mut rng: StdRng = rand::SeedableRng::seed_from_u64(0);
let mut ids = vec![];
for _ in 0..SIZE {
let pos = rng.gen::<usize>() % (ids.len() + 1);
ids.push(tree.create_at(TreeParentId::Root, pos).unwrap());
}
b.iter(|| {
for _ in 0..*i {
tree.create_at(TreeParentId::Root, 0).unwrap();
let i = rng.gen::<usize>() % SIZE;
let j = rng.gen::<usize>() % SIZE;
tree.mov(ids[i], TreeParentId::Node(ids[j]))
.unwrap_or_default();
}
})
},
);
}
group.bench_function("1000 node checkout 10^3", |b| {
let loro = LoroDoc::default();
loro.start_auto_commit();
let tree = loro.get_tree("tree");
let mut ids = vec![];
let mut versions = vec![];
let size = 1000;
for _ in 0..size {
ids.push(tree.create(TreeParentId::Root).unwrap())
}
let mut rng: StdRng = rand::SeedableRng::seed_from_u64(0);
let mut n = 1000;
while n > 0 {
let i = rng.gen::<usize>() % size;
let j = rng.gen::<usize>() % size;
if tree.mov(ids[i], TreeParentId::Node(ids[j])).is_ok() {
versions.push(loro.oplog_frontiers());
n -= 1;
};
}
b.iter(|| {
for _ in 0..1000 {
let i = rng.gen::<usize>() % 1000;
let f = &versions[i];
loro.checkout(f).unwrap();
}
})
});
group.bench_function("300 deep node random checkout 10^3", |b| {
let depth = 300;
let loro = LoroDoc::default();
loro.start_auto_commit();
let tree = loro.get_tree("tree");
let mut ids = vec![];
let mut versions = vec![];
let id1 = tree.create(TreeParentId::Root).unwrap();
ids.push(id1);
versions.push(loro.oplog_frontiers());
for _ in 1..depth {
let id = tree
.create(TreeParentId::Node(*ids.last().unwrap()))
.unwrap();
ids.push(id);
versions.push(loro.oplog_frontiers());
}
let mut rng: StdRng = rand::SeedableRng::seed_from_u64(0);
b.iter(|| {
for _ in 0..1000 {
let i = rng.gen::<usize>() % depth;
let f = &versions[i];
loro.checkout(f).unwrap();
}
})
});
group.bench_function("realtime tree move", |b| {
let doc_a = LoroDoc::default();
let doc_b = LoroDoc::default();
doc_a.start_auto_commit();
doc_b.start_auto_commit();
let tree_a = doc_a.get_tree("tree");
let tree_b = doc_b.get_tree("tree");
let mut ids = vec![];
let size = 1000;
for _ in 0..size {
ids.push(tree_a.create(TreeParentId::Root).unwrap())
}
doc_b.import(&doc_a.export_snapshot().unwrap()).unwrap();
let mut rng: StdRng = rand::SeedableRng::seed_from_u64(0);
let n = 1000;
b.iter(|| {
for t in 0..n {
let i = rng.gen::<usize>() % size;
let j = rng.gen::<usize>() % size;
if t % 2 == 0 {
tree_a
.mov(ids[i], TreeParentId::Node(ids[j]))
.unwrap_or_default();
doc_b.import(&doc_a.export_from(&doc_b.oplog_vv())).unwrap();
} else {
tree_b
.mov(ids[i], TreeParentId::Node(ids[j]))
.unwrap_or_default();
doc_a.import(&doc_b.export_from(&doc_a.oplog_vv())).unwrap();
}
}
})
});
group.finish();
}
}
criterion_group!(benches, tree::tree_move);
criterion_main!(benches);