use std::hint::black_box;
use std::time::Duration;
use criterion::{Criterion, criterion_main};
use pdfrum::{Document, RasterBackend, RenderOptions, RenderSession, VelloCpuBackend};
use pdfrum_corpus::{CORPUS, bytes};
use pdfrum_raster_agg::AggBackend;
use pdfrum_raster_tinyskia::TinySkiaBackend;
fn cold_samples(stem: &str) -> usize {
match stem {
"image_bug_718762" | "image_bug_583804" | "image_bug_898443" => 10,
"image_en_fqa" | "vector_en_system" => 20,
_ => 50,
}
}
fn warm_samples(stem: &str) -> usize {
match stem {
"image_bug_718762" | "image_bug_583804" | "image_bug_898443" => 10,
_ => 20,
}
}
fn leaves_a_large_heap(stem: &str) -> bool {
matches!(
stem,
"image_bug_718762" | "image_bug_583804" | "image_bug_898443"
)
}
fn light_then_heavy() -> impl Iterator<Item = &'static pdfrum_corpus::Doc> {
CORPUS
.iter()
.filter(|doc| !leaves_a_large_heap(doc.stem))
.chain(CORPUS.iter().filter(|doc| leaves_a_large_heap(doc.stem)))
}
fn cold<B: RasterBackend>(c: &mut Criterion, name: &str, backend: &B) {
let mut group = c.benchmark_group(name);
let options = RenderOptions::default();
for doc in light_then_heavy() {
let Ok(opened) = Document::from_bytes(bytes(doc.stem)) else {
continue;
};
group.sample_size(cold_samples(doc.stem));
group.bench_function(format!("{}/{}", doc.class.name(), doc.stem), |b| {
b.iter(|| {
let mut session = RenderSession::new();
for page in opened.pages() {
black_box(page.render_on(backend, &options, &mut session).ok());
}
});
});
}
group.finish();
}
fn warm<B: RasterBackend>(c: &mut Criterion, name: &str, backend: &B) {
let mut group = c.benchmark_group(name);
let options = RenderOptions::default();
for doc in light_then_heavy() {
let Ok(opened) = Document::from_bytes(bytes(doc.stem)) else {
continue;
};
group.sample_size(warm_samples(doc.stem));
group.bench_function(format!("{}/{}", doc.class.name(), doc.stem), |b| {
let mut session = RenderSession::new();
for page in opened.pages() {
drop(page.render_on(backend, &options, &mut session));
}
b.iter(|| {
for page in opened.pages() {
black_box(page.render_on(backend, &options, &mut session).ok());
}
});
});
}
group.finish();
}
fn cold_agg(c: &mut Criterion) {
cold(c, "render-cold-agg", &AggBackend::new());
}
fn cold_tinyskia(c: &mut Criterion) {
cold(c, "render-cold-tinyskia", &TinySkiaBackend::new());
}
fn cold_vello_cpu(c: &mut Criterion) {
cold(c, "render-cold-vello-cpu", &VelloCpuBackend::new());
}
fn warm_agg(c: &mut Criterion) {
warm(c, "render-warm-agg", &AggBackend::new());
}
fn warm_tinyskia(c: &mut Criterion) {
warm(c, "render-warm-tinyskia", &TinySkiaBackend::new());
}
fn warm_vello_cpu(c: &mut Criterion) {
warm(c, "render-warm-vello-cpu", &VelloCpuBackend::new());
}
#[allow(missing_docs, reason = "the item is generated by criterion_group!")]
mod group {
use super::{
Criterion, Duration, cold_agg, cold_tinyskia, cold_vello_cpu, warm_agg, warm_tinyskia,
warm_vello_cpu,
};
use criterion::criterion_group;
criterion_group! {
name = benches;
config = Criterion::default()
.measurement_time(Duration::from_secs(5))
.warm_up_time(Duration::from_secs(2))
.sample_size(50);
targets = cold_agg, cold_tinyskia, cold_vello_cpu, warm_agg, warm_tinyskia, warm_vello_cpu
}
}
criterion_main!(group::benches);