use criterion::BenchmarkId; use criterion::Throughput; use criterion::{black_box, criterion_group, criterion_main, Criterion}; use image::imageops; use image::GenericImageView; use load_image as load_image_crate; use stb_image::image::load as stb_load; use stb_image::image::LoadResult; use photosync::library::load_image; use photosync::library::resize; use photosync::library::save_to_jpeg_bytes; use photosync::library::FilterType; pub fn criterion_benchmark(c: &mut Criterion) { const TEST_IMAGE_PATH: &'static str = "testdata/image.jpg"; let img = load_image(TEST_IMAGE_PATH, None, None).expect("failed to load test image"); c.bench_function("Load image", |b| { b.iter(|| black_box(load_image(TEST_IMAGE_PATH, None, None))) }); c.bench_function("Load image 256x256", |b| { b.iter(|| black_box(load_image(TEST_IMAGE_PATH, Some(256), Some(256)))) }); c.bench_function("Load load_image", |b| { b.iter(|| { black_box(load_image_crate::load_image(TEST_IMAGE_PATH, true).expect("failed to load")) }) }); c.bench_function("Load stb_image", |b| { b.iter(|| match stb_load(TEST_IMAGE_PATH) { LoadResult::Error(err) => panic!(err), LoadResult::ImageU8(img) => { black_box(img); } LoadResult::ImageF32(img) => { black_box(img); } }) }); let mut group = c.benchmark_group("Resizing"); for size in [ (None, None), (Some(256), Some(256)), (Some(512), Some(512)), (Some(1024), Some(1024)), (Some(2048), Some(2048)), ] .iter() { let (w, h) = size; for filter in [ FilterType::Builtin(imageops::Nearest), FilterType::Builtin(imageops::CatmullRom), FilterType::Builtin(imageops::Lanczos3), FilterType::Nearest, ] .iter() { let (img_w, img_h) = img.dimensions(); let pixels = (img_w * img_h) as u64; group.throughput(Throughput::Elements(pixels)); group.bench_with_input( BenchmarkId::new( format!("{:?}", filter), format!( "{}x{}", w.map(|i| i.to_string()).unwrap_or("FULL".to_string()), h.map(|i| i.to_string()).unwrap_or("FULL".to_string()) ), ), &(size, filter), |b, (size, &filter)| b.iter(|| black_box(resize(&img, **size, filter))), ); } group.bench_with_input( BenchmarkId::new( "Save to bytes", format!( "{}x{}", w.map(|i| i.to_string()).unwrap_or("FULL".to_string()), h.map(|i| i.to_string()).unwrap_or("FULL".to_string()) ), ), size, |b, size| { let small_img = resize(&img, *size, FilterType::Builtin(imageops::Lanczos3)); b.iter(|| black_box(save_to_jpeg_bytes(&small_img))) }, ); group.bench_with_input( BenchmarkId::new( "Full pipeline Lanczos3", format!( "{}x{}", w.map(|i| i.to_string()).unwrap_or("FULL".to_string()), h.map(|i| i.to_string()).unwrap_or("FULL".to_string()) ), ), size, |b, size| { b.iter(|| { let img = load_image(TEST_IMAGE_PATH, size.0, size.1) .expect("failed to load test image"); let small_img = resize(&img, *size, FilterType::Builtin(imageops::Lanczos3)); black_box(save_to_jpeg_bytes(&small_img)) }) }, ); } group.finish(); } criterion_group!(benches, criterion_benchmark); criterion_main!(benches);