use criterion::{Criterion, black_box};
use molframe_bench::{Sample, structure, structure_with_atoms};
use molframe_core::ExecutionContext;
use molframe_core::contract::AnalysisPolicy;
use molframe_query::{Groups, Query, col};
use molframe_spatial::{SpatialBackend, StructureSpatial};
fn bench_queries(c: &mut Criterion) {
let context = ExecutionContext::default();
let structure = structure(Sample::Medium);
let policy = AnalysisPolicy::default();
let groups = Groups::new();
let spatial =
match StructureSpatial::new(&structure, &policy, SpatialBackend::CellList, &context) {
Ok(spatial) => spatial,
Err(error) => panic!("query spatial benchmark fixture failed: {error:?}"),
};
let typed = Query::from_builder(col::bfactor().gt(20.0));
let geometric = Query::from_builder(col::within(5.0, col::chain().eq("A")));
let residue_expansion = Query::from_builder(col::by_residue(col::name().eq("CA")));
let textual = match Query::compile("chain A and bfactor > 20") {
Ok(query) => query,
Err(findings) => panic!("query bench fixture failed: {findings:?}"),
};
for query in [&typed, &textual, &geometric, &residue_expansion] {
if let Err(findings) = query.evaluate(&structure, &policy, &groups, Some(&spatial)) {
panic!("query benchmark evaluation failed: {findings:?}");
}
}
let mut group = c.benchmark_group("query_evaluation");
group.bench_function("typed", |b| {
b.iter(|| black_box(typed.evaluate(&structure, &policy, &groups, Some(&spatial))));
});
group.bench_function("textual", |b| {
b.iter(|| black_box(textual.evaluate(&structure, &policy, &groups, Some(&spatial))));
});
group.bench_function("geometric_within", |b| {
b.iter(|| black_box(geometric.evaluate(&structure, &policy, &groups, Some(&spatial))));
});
group.bench_function("residue_expansion", |b| {
b.iter(|| {
black_box(residue_expansion.evaluate(&structure, &policy, &groups, Some(&spatial)))
});
});
group.finish();
c.bench_function("query_compile/complex", |b| {
b.iter(|| {
black_box(Query::compile(
"protein and name C* and bfactor > 20 and within 5 of (resname HEM)",
))
});
});
}
fn bench_prune(c: &mut Criterion) {
let structure = structure_with_atoms(100_000);
let policy = AnalysisPolicy::default();
let groups = Groups::new();
let query = match Query::compile("element ZN") {
Ok(query) => query,
Err(findings) => panic!("query bench fixture failed: {findings:?}"),
};
if let Err(findings) = query.evaluate(&structure, &policy, &groups, None) {
panic!("query benchmark evaluation failed: {findings:?}");
}
let mut group = c.benchmark_group("query_prune");
group.bench_function("element_zn_100k", |b| {
b.iter(|| black_box(query.evaluate(&structure, &policy, &groups, None)));
});
group.finish();
}
fn main() {
let mut criterion = Criterion::default().configure_from_args();
bench_queries(&mut criterion);
bench_prune(&mut criterion);
criterion.final_summary();
}