diff --git a/Cargo.toml b/Cargo.toml index 33ae3e8..e1e99ef 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,7 +21,7 @@ structopt = "0.3.9" yup-oauth2 = "^3.1" warp = "0.1" serde = { version = "1.0.104", features = ["derive"] } -image = "0.23.0" +image = { version = "0.23.0" } #, default-features = false, features = ["jpeg"] } rust-embed = "5.2.0" mime_guess = "2.0.1" rocksdb = "0.13.0" diff --git a/benches/image.rs b/benches/image.rs index 6f1da19..237fca1 100644 --- a/benches/image.rs +++ b/benches/image.rs @@ -1,9 +1,13 @@ +use criterion::BenchmarkId; +use criterion::Throughput; use criterion::{black_box, criterion_group, criterion_main, Criterion}; use image::imageops::FilterType; +use image::GenericImageView; use photosync::library::load_image; use photosync::library::resize; +use photosync::library::save_to_jpeg_bytes; pub fn criterion_benchmark(c: &mut Criterion) { const TEST_IMAGE_PATH: &'static str = "testdata/image.jpg"; @@ -11,15 +15,78 @@ pub fn criterion_benchmark(c: &mut Criterion) { c.bench_function("Load image", |b| { b.iter(|| black_box(load_image(TEST_IMAGE_PATH))) }); - c.bench_function("Resize image full Nearest", |b| { - b.iter(|| black_box(resize(&img, (None, None), FilterType::Nearest))) - }); - c.bench_function("Resize image full CatmullRom", |b| { - b.iter(|| black_box(resize(&img, (None, None), FilterType::CatmullRom))) - }); - c.bench_function("Resize image full Lanczos3", |b| { - b.iter(|| black_box(resize(&img, (None, None), FilterType::Lanczos3))) - }); + + 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::Nearest, + FilterType::CatmullRom, + FilterType::Lanczos3, + ] + .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::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).expect("failed to load test image"); + let small_img = resize(&img, *size, FilterType::Lanczos3); + black_box(save_to_jpeg_bytes(&small_img)) + }) + }, + ); + } + group.finish(); } criterion_group!(benches, criterion_benchmark); diff --git a/src/library.rs b/src/library.rs index 3fa8a67..9623aa2 100644 --- a/src/library.rs +++ b/src/library.rs @@ -55,7 +55,7 @@ pub fn resize( img.resize_to_fill(w, h, filter) } -pub fn save_to_jpeg_bytes(img: DynamicImage) -> ImageResult> { +pub fn save_to_jpeg_bytes(img: &DynamicImage) -> ImageResult> { let mut buf = Vec::new(); img.write_to(&mut buf, ImageFormat::Jpeg)?; Ok(buf) @@ -203,8 +203,8 @@ impl Library { let orig_img = load_image(&path).map_err(|e| io::Error::new(io::ErrorKind::Other, e))?; let img = resize(&orig_img, dimensions, filter); - let buf = - save_to_jpeg_bytes(img).map_err(|e| io::Error::new(io::ErrorKind::Other, e))?; + let buf = save_to_jpeg_bytes(&img) + .map_err(|e| io::Error::new(io::ErrorKind::Other, e))?; Ok(buf) } } diff --git a/testdata/image.jpg b/testdata/image.jpg index f6c4168..cf94abb 100644 Binary files a/testdata/image.jpg and b/testdata/image.jpg differ