//! End-to-end benchmark: generate log lines, filter, render to a buffer.
//!
//! Gives a single "lines per second" number that captures the full pipeline.
use criterion::{black_box, criterion_group, criterion_main, Criterion, Throughput};
use ripgrab::filter::{dsl, FilterSet, MatchOutcome};
use ripgrab::render::mode::stream::StreamRenderer;
mod fixtures;
fn bench_end_to_end(c: &mut Criterion) {
let lines = fixtures::access_log(fixtures::DEFAULT_LINES);
let filter = FilterSet::compile(&[], &[], None).unwrap();
let compiled = dsl::parse_and_compile("status >= 400").unwrap();
let mut group = c.benchmark_group("pipeline");
group.throughput(Throughput::Elements(lines.len() as u64));
group.bench_function("end-to-end", |b| {
b.iter(|| {
let mut buf = Vec::with_capacity(lines.iter().map(|l| l.len() + 1).sum());
let mut renderer = StreamRenderer::new(&mut buf, true, false);
let mut ctx = dsl::EvalContext::new();
for line in &lines {
ctx.clear();
ctx.set("status", extract_status(line));
if !dsl::evaluate(&compiled, &ctx) {
continue;
}
if let MatchOutcome::Plain = filter.apply(line) {
renderer.render("bench.log", black_box(line)).unwrap();
}
}
black_box(buf)
});
});
group.finish();
}
fn extract_status(line: &str) -> &str {
line.split_whitespace()
.find_map(|f| f.strip_prefix("status="))
.unwrap_or("0")
}
criterion_group!(benches, bench_end_to_end);
criterion_main!(benches);