From fddcd4626953d89a368bd207f997f9ee43d63349 Mon Sep 17 00:00:00 2001 From: "Sergey \"Shnatsel\" Davidoff" Date: Sun, 29 Sep 2024 13:38:42 +0100 Subject: [PATCH] Expose filtering as a benchable API and add a benchmark for it --- benches/filter.rs | 56 +++++++++++++++++++++++++++++++++++++++++++ src/benchable_apis.rs | 5 ++++ 2 files changed, 61 insertions(+) create mode 100644 benches/filter.rs diff --git a/benches/filter.rs b/benches/filter.rs new file mode 100644 index 00000000..f4df4b8e --- /dev/null +++ b/benches/filter.rs @@ -0,0 +1,56 @@ +//! Usage example: +//! +//! ``` +//! $ alias bench="rustup run nightly cargo bench" +//! $ bench --bench=filter --features=benchmarks,unstable -- --save-baseline my_baseline +//! ... tweak something, say the Sub filter ... +//! $ bench --bench=filter --features=benchmarks,unstable -- filter=Sub --baseline my_baseline +//! ``` + +use criterion::{criterion_group, criterion_main, Criterion, Throughput}; +use png::benchable_apis::filter; +use png::FilterType; +use rand::Rng; + +fn filter_all(c: &mut Criterion) { + let bpps = [1, 2, 3, 4, 6, 8]; + let filters = [ + FilterType::Sub, + FilterType::Up, + FilterType::Avg, + FilterType::Paeth, + ]; + for &filter in filters.iter() { + for &bpp in bpps.iter() { + bench_filter(c, filter, bpp); + } + } +} + +criterion_group!(benches, filter_all); +criterion_main!(benches); + +fn bench_filter(c: &mut Criterion, filter: FilterType, bpp: u8) { + let mut group = c.benchmark_group("filter"); + + fn get_random_bytes(rng: &mut R, n: usize) -> Vec { + use rand::Fill; + let mut result = vec![0u8; n]; + result.as_mut_slice().try_fill(rng).unwrap(); + result + } + let mut rng = rand::thread_rng(); + let row_size = 4096 * (bpp as usize); + let two_rows = get_random_bytes(&mut rng, row_size * 2); + + group.throughput(Throughput::Bytes(row_size as u64)); + group.bench_with_input( + format!("filter={filter:?}/bpp={bpp}"), + &two_rows, + |b, two_rows| { + let (prev_row, curr_row) = two_rows.split_at(row_size); + let mut curr_row = curr_row.to_vec(); + b.iter(|| filter(filter, bpp, prev_row, curr_row.as_mut_slice())); + }, + ); +} diff --git a/src/benchable_apis.rs b/src/benchable_apis.rs index 17b0b0d6..e52fe9d8 100644 --- a/src/benchable_apis.rs +++ b/src/benchable_apis.rs @@ -12,6 +12,11 @@ pub fn unfilter(filter: FilterType, tbpp: u8, previous: &[u8], current: &mut [u8 crate::filter::unfilter(filter, tbpp, previous, current) } +pub fn filter(filter: FilterType, tbpp: u8, previous: &[u8], current: &mut [u8]) { + let tbpp = BytesPerPixel::from_usize(tbpp as usize); + crate::filter::filter(filter, tbpp, previous, current) +} + pub use crate::decoder::transform::{create_transform_fn, TransformFn}; pub fn create_info_from_plte_trns_bitdepth<'a>(