use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion};
use edgevec::filter::strategy::{
calculate_oversample, is_contradiction, is_tautology, select_strategy, FilterStrategy,
POSTFILTER_THRESHOLD, PREFILTER_THRESHOLD,
};
use edgevec::filter::{parse, FilterExpr};
use std::hint::black_box;
fn bench_strategy_selection(c: &mut Criterion) {
let mut group = c.benchmark_group("strategy_selection");
let expressions = [
("simple_eq", "category = \"gpu\""),
("simple_range", "price BETWEEN 100 AND 500"),
("compound_and", "category = \"gpu\" AND price < 500"),
("compound_or", "category = \"gpu\" OR category = \"cpu\""),
(
"complex",
"(category = \"gpu\" AND price < 500) OR (rating >= 4.5 AND stock > 0)",
),
(
"deeply_nested",
"((a = 1 AND b = 2) OR (c = 3 AND d = 4)) AND ((e = 5 OR f = 6) AND g = 7)",
),
];
for (name, expr_str) in expressions {
let _expr = parse(expr_str).expect("Valid expression");
group.bench_with_input(
BenchmarkId::new("parse_and_select", name),
&0.5f32,
|b, &selectivity| b.iter(|| black_box(select_strategy(black_box(selectivity)))),
);
}
group.finish();
}
fn bench_tautology_detection(c: &mut Criterion) {
let mut group = c.benchmark_group("tautology_detection");
let tautologies = [
("literal_true", FilterExpr::LiteralBool(true)),
(
"or_with_not",
FilterExpr::Or(
Box::new(FilterExpr::Field("x".to_string())),
Box::new(FilterExpr::Not(Box::new(FilterExpr::Field(
"x".to_string(),
)))),
),
),
(
"between_all",
FilterExpr::Between(
Box::new(FilterExpr::Field("x".to_string())),
Box::new(FilterExpr::LiteralInt(i64::MIN)),
Box::new(FilterExpr::LiteralInt(i64::MAX)),
),
),
];
for (name, expr) in &tautologies {
group.bench_with_input(BenchmarkId::new("is_tautology", name), expr, |b, e| {
b.iter(|| black_box(is_tautology(black_box(e))))
});
}
let contradictions = [
("literal_false", FilterExpr::LiteralBool(false)),
(
"and_with_not",
FilterExpr::And(
Box::new(FilterExpr::Field("x".to_string())),
Box::new(FilterExpr::Not(Box::new(FilterExpr::Field(
"x".to_string(),
)))),
),
),
(
"impossible_range",
FilterExpr::Between(
Box::new(FilterExpr::Field("x".to_string())),
Box::new(FilterExpr::LiteralInt(100)),
Box::new(FilterExpr::LiteralInt(50)),
),
),
];
for (name, expr) in &contradictions {
group.bench_with_input(BenchmarkId::new("is_contradiction", name), expr, |b, e| {
b.iter(|| black_box(is_contradiction(black_box(e))))
});
}
group.finish();
}
fn bench_oversample_calculation(c: &mut Criterion) {
let mut group = c.benchmark_group("oversample_calculation");
let selectivities = [0.01, 0.05, 0.1, 0.25, 0.5, 0.75, 0.9, 0.99];
for selectivity in selectivities {
group.bench_with_input(
BenchmarkId::new("calculate_oversample", format!("{:.2}", selectivity)),
&selectivity,
|b, &s| b.iter(|| black_box(calculate_oversample(black_box(s)))),
);
}
group.finish();
}
fn bench_threshold_boundaries(c: &mut Criterion) {
let mut group = c.benchmark_group("threshold_boundaries");
let boundary_selectivities = [
("postfilter_below", POSTFILTER_THRESHOLD - 0.01),
("postfilter_at", POSTFILTER_THRESHOLD),
("postfilter_above", POSTFILTER_THRESHOLD + 0.01),
("hybrid_low", 0.2),
("hybrid_mid", 0.5),
("hybrid_high", 0.7),
("prefilter_below", PREFILTER_THRESHOLD - 0.01),
("prefilter_at", PREFILTER_THRESHOLD),
("prefilter_above", PREFILTER_THRESHOLD + 0.01),
];
for (name, selectivity) in boundary_selectivities {
group.bench_with_input(
BenchmarkId::new("select_strategy", name),
&selectivity,
|b, &s| b.iter(|| black_box(select_strategy(black_box(s)))),
);
}
group.finish();
}
fn bench_auto_vs_explicit(c: &mut Criterion) {
let mut group = c.benchmark_group("auto_vs_explicit");
group.bench_function("explicit_postfilter", |b| {
b.iter(|| black_box(FilterStrategy::PostFilter { oversample: 3.0 }))
});
group.bench_function("explicit_prefilter", |b| {
b.iter(|| black_box(FilterStrategy::PreFilter))
});
group.bench_function("explicit_hybrid", |b| {
b.iter(|| {
black_box(FilterStrategy::Hybrid {
oversample_min: 1.5,
oversample_max: 10.0,
})
})
});
group.bench_function("auto_selection", |b| {
b.iter(|| black_box(select_strategy(black_box(0.5))))
});
group.finish();
}
criterion_group!(
benches,
bench_strategy_selection,
bench_tautology_detection,
bench_oversample_calculation,
bench_threshold_boundaries,
bench_auto_vs_explicit,
);
criterion_main!(benches);