use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion};
use yang5::context::{Context, ContextFlags};
use yang5::data::{Data, DataDiffFlags, DataTree, DataValidationFlags};
static SEARCH_DIR: &str = "./assets/yang/";
fn data_generate(ctx: &Context, interfaces: u32) -> DataTree {
let mut dtree = DataTree::new(ctx);
for i in 1..=interfaces {
let changes = [
(format!("/ietf-interfaces:interfaces/interface[name='eth{}']", i), None),
(format!("/ietf-interfaces:interfaces/interface[name='eth{}']/type", i), Some("iana-if-type:ethernetCsmacd")),
(format!("/ietf-interfaces:interfaces/interface[name='eth{}']/enabled", i), Some("true")),
];
for (xpath, value) in &changes {
dtree
.new_path(xpath, *value, false)
.expect("Failed to edit data tree");
}
}
dtree
}
fn criterion_benchmark(c: &mut Criterion) {
let tree_sizes = [
1 * 1024,
2 * 1024,
4 * 1024,
8 * 1024,
16 * 1024,
32 * 1024,
64 * 1024,
];
let mut ctx = Context::new(ContextFlags::NO_YANGLIBRARY)
.expect("Failed to create context");
ctx.set_searchdir(SEARCH_DIR)
.expect("Failed to set YANG search directory");
for module_name in &["ietf-interfaces", "iana-if-type"] {
ctx.load_module(module_name, None, &[])
.expect("Failed to load module");
}
let mut group = c.benchmark_group("DataTree.diff() / tree size");
for size in &tree_sizes {
let dtree = data_generate(&ctx, *size);
let dtree_base = data_generate(&ctx, *size + 1024);
group.bench_with_input(
BenchmarkId::from_parameter(size),
size,
|b, _| {
b.iter(|| {
dtree
.diff(&dtree_base, DataDiffFlags::empty())
.expect("Failed to compare data trees");
});
},
);
}
group.finish();
let mut group = c.benchmark_group("DataTree.find() / tree size");
for size in &tree_sizes {
let dtree = data_generate(&ctx, *size);
group.bench_with_input(
BenchmarkId::from_parameter(size),
size,
|b, _| {
b.iter(|| {
for dnode in dtree.traverse() {
let path = dnode.path();
dtree.find_path(&path).expect("Failed to find data");
}
});
},
);
}
group.finish();
let mut group = c.benchmark_group("DataTree.validate() / tree size");
for size in &tree_sizes {
let mut dtree = data_generate(&ctx, *size);
group.bench_with_input(
BenchmarkId::from_parameter(size),
size,
|b, _| {
b.iter(|| {
dtree
.validate(
DataValidationFlags::NO_STATE
| DataValidationFlags::PRESENT,
)
.expect("Failed to validate data tree")
})
},
);
}
group.finish();
}
criterion_group!(benches, criterion_benchmark);
criterion_main!(benches);