- Fixed benchmark for resizing of RGB images.

- Added benchmark for resizing of RGBA images.
This commit is contained in:
Kirill Kuzminykh
2021-07-03 18:53:07 +03:00
parent d098c213ad
commit 627d396fee
3 changed files with 207 additions and 25 deletions
+21 -10
View File
@@ -24,24 +24,35 @@ Other Rust libraries used to compare of resizing speed:
Resize algorithms:
- Nearest
- Bilinear
- CatmullRom
- Lanczos3
- Convolution with Bilinear filter
- Convolution with CatmullRom filter
- Convolution with Lanczos3 filter
### Resize 4928x3279 => 852x567
### Resize RGB image 4928x3279 => 852x567
- Source image [nasa-4928x3279.png](https://github.com/Cykooz/fast_image_resize/blob/main/data/nasa-4928x3279.png)
- Numbers in table is time of image resizing in milliseconds.
| | Nearest | Bilinear | CatmullRom | Lanczos3 |
|------------|:-------:|:--------:|:----------:|:--------:|
| image | 101.98 | 204.79 | 307.0 | 421.58 |
| resize | 23.139 | 103.84 | 182.36 | 261.64 |
| fir native | 0.486 | 54.479 | 81.625 | 113.37 |
| fir sse4.1 | - | 12.08 | 18.733 | 26.689 |
| fir avx2 | - | 9.58 | 14.319 | 20.133 |
| image | 105.38 | 204.21 | 301.58 | 399.52 |
| resize | 16.223 | 72.447 | 132.64 | 193.26 |
| fir native | 0.476 | 57.003 | 87.564 | 120.65 |
| fir sse4.1 | - | 12.143 | 18.662 | 26.334 |
| fir avx2 | - | 9.346 | 13.342 | 18.934 |
fir - fast_image_resize
### Resize RGBA image 4928x3279 => 852x567
- Source image [nasa-4928x3279.png](https://github.com/Cykooz/fast_image_resize/blob/main/data/nasa-4928x3279.png)
- Numbers in table is time of image resizing in milliseconds.
| | Nearest | Bilinear | CatmullRom | Lanczos3 |
|------------|:-------:|:--------:|:----------:|:--------:|
| image | 110.45 | 264.84 | 421.25 | 596.17 |
| resize | 23.919 | 100.38 | 173.62 | 247.39 |
| fir native | 13.832 | 70.448 | 100.87 | 133.84 |
| fir sse4.1 | 12.03 | 23.721 | 30.266 | 37.874 |
| fir avx2 | 6.949 | 15.873 | 19.956 | 25.527 |
## Examples of code
+173 -11
View File
@@ -3,19 +3,20 @@ use std::num::NonZeroU32;
use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion};
use image::imageops;
use resize::px::RGBA;
use resize::Pixel::RGBA8;
use rgb::FromSlice;
use resize::Pixel::{RGB8, RGBA8};
use rgb::{FromSlice, RGB};
use fast_image_resize::ImageData;
use fast_image_resize::{CpuExtensions, FilterType, PixelType, ResizeAlg, Resizer};
use fast_image_resize::{ImageData, MulDiv};
mod utils;
pub fn bench_downscale(c: &mut Criterion) {
pub fn bench_downscale_rgb(c: &mut Criterion) {
let src_image = utils::get_big_rgb_image();
let new_width = NonZeroU32::new(852).unwrap();
let new_height = NonZeroU32::new(567).unwrap();
let mut group = c.benchmark_group("Downscale (4928x3279 => 852x567)");
let mut group = c.benchmark_group("Downscale RGB (4928x3279 => 852x567)");
for alg_num in 0..4 {
// image crate
@@ -39,8 +40,8 @@ pub fn bench_downscale(c: &mut Criterion) {
// resize crate
// https://crates.io/crates/resize
let resize_src_image = src_image.as_raw().as_rgba();
let mut dst = vec![RGBA::new(0, 0, 0, 0); (new_width.get() * new_height.get()) as usize];
let resize_src_image = src_image.as_raw().as_rgb();
let mut dst = vec![RGB::new(0, 0, 0); (new_width.get() * new_height.get()) as usize];
group.bench_with_input(
BenchmarkId::new("resize", alg_num),
@@ -58,7 +59,7 @@ pub fn bench_downscale(c: &mut Criterion) {
src_image.height() as usize,
new_width.get() as usize,
new_height.get() as usize,
RGBA8,
RGB8,
filter,
)
.unwrap();
@@ -68,11 +69,12 @@ pub fn bench_downscale(c: &mut Criterion) {
},
);
// fast_image_resize crate
// fast_image_resize crate;
let src_rgba_image = utils::get_big_rgba_image();
let src_image_data = ImageData::new(
NonZeroU32::new(src_image.width()).unwrap(),
NonZeroU32::new(src_image.height()).unwrap(),
src_image.as_raw(),
src_rgba_image.as_raw(),
PixelType::U8x4,
)
.unwrap();
@@ -149,5 +151,165 @@ pub fn bench_downscale(c: &mut Criterion) {
group.finish();
}
criterion_group!(benches, bench_downscale,);
pub fn bench_downscale_rgba(c: &mut Criterion) {
let src_image = utils::get_big_rgba_image();
let new_width = NonZeroU32::new(852).unwrap();
let new_height = NonZeroU32::new(567).unwrap();
let mut group = c.benchmark_group("Downscale RGBA (4928x3279 => 852x567)");
for alg_num in 0..4 {
// image crate
// https://crates.io/crates/image
group.bench_with_input(
BenchmarkId::new("image", alg_num),
&alg_num,
|b, alg_num| {
b.iter(|| {
let filter = match alg_num {
0 => imageops::Nearest,
1 => imageops::Triangle,
2 => imageops::CatmullRom,
3 => imageops::Lanczos3,
_ => return,
};
imageops::resize(&src_image, new_width.get(), new_height.get(), filter);
})
},
);
// resize crate
// https://crates.io/crates/resize
let resize_src_image = src_image.as_raw().as_rgba();
let mut dst = vec![RGBA::new(0, 0, 0, 0); (new_width.get() * new_height.get()) as usize];
group.bench_with_input(
BenchmarkId::new("resize", alg_num),
&alg_num,
|b, alg_num| {
let filter = match alg_num {
0 => resize::Type::Point,
1 => resize::Type::Triangle,
2 => resize::Type::Catrom,
3 => resize::Type::Lanczos3,
_ => return,
};
let mut resizer = resize::new(
src_image.width() as usize,
src_image.height() as usize,
new_width.get() as usize,
new_height.get() as usize,
RGBA8,
filter,
)
.unwrap();
b.iter(|| {
resizer.resize(resize_src_image, &mut dst).unwrap();
})
},
);
// fast_image_resize crate;
let src_image_data = ImageData::new(
NonZeroU32::new(src_image.width()).unwrap(),
NonZeroU32::new(src_image.height()).unwrap(),
src_image.as_raw(),
PixelType::U8x4,
)
.unwrap();
let src_view = src_image_data.src_view();
let mut premultiplied_src_image = ImageData::new_owned(
NonZeroU32::new(src_image.width()).unwrap(),
NonZeroU32::new(src_image.height()).unwrap(),
PixelType::U8x4,
);
let mut dst_image = ImageData::new_owned(new_width, new_height, PixelType::U8x4);
let mut dst_view = dst_image.dst_view();
let mut fast_resizer = Resizer::new(ResizeAlg::Nearest);
let mut mul_div = MulDiv::default();
unsafe {
fast_resizer.set_cpu_extensions(CpuExtensions::None);
mul_div.set_cpu_extensions(CpuExtensions::None);
}
group.bench_with_input(
BenchmarkId::new("fast_wo_simd", alg_num),
&alg_num,
|b, alg_num| {
let resize_alg = match alg_num {
0 => ResizeAlg::Nearest,
1 => ResizeAlg::Convolution(FilterType::Bilinear),
2 => ResizeAlg::Convolution(FilterType::CatmulRom),
3 => ResizeAlg::Convolution(FilterType::Lanczos3),
_ => return,
};
fast_resizer.algorithm = resize_alg;
b.iter(|| {
mul_div
.multiply_alpha(&src_view, &mut premultiplied_src_image.dst_view())
.unwrap();
fast_resizer.resize(&premultiplied_src_image.src_view(), &mut dst_view);
mul_div.divide_alpha_inplace(&mut dst_view).unwrap();
})
},
);
let mut fast_resizer = Resizer::new(ResizeAlg::Nearest);
unsafe {
fast_resizer.set_cpu_extensions(CpuExtensions::Sse4_1);
mul_div.set_cpu_extensions(CpuExtensions::Sse4_1);
}
group.bench_with_input(
BenchmarkId::new("fast_sse4", alg_num),
&alg_num,
|b, alg_num| {
let resize_alg = match alg_num {
0 => ResizeAlg::Nearest,
1 => ResizeAlg::Convolution(FilterType::Bilinear),
2 => ResizeAlg::Convolution(FilterType::CatmulRom),
3 => ResizeAlg::Convolution(FilterType::Lanczos3),
_ => return,
};
fast_resizer.algorithm = resize_alg;
b.iter(|| {
mul_div
.multiply_alpha(&src_view, &mut premultiplied_src_image.dst_view())
.unwrap();
fast_resizer.resize(&premultiplied_src_image.src_view(), &mut dst_view);
mul_div.divide_alpha_inplace(&mut dst_view).unwrap();
})
},
);
let mut fast_resizer = Resizer::new(ResizeAlg::Nearest);
unsafe {
fast_resizer.set_cpu_extensions(CpuExtensions::Avx2);
mul_div.set_cpu_extensions(CpuExtensions::Avx2);
}
group.bench_with_input(
BenchmarkId::new("fast_avx2", alg_num),
&alg_num,
|b, alg_num| {
let resize_alg = match alg_num {
0 => ResizeAlg::Nearest,
1 => ResizeAlg::Convolution(FilterType::Bilinear),
2 => ResizeAlg::Convolution(FilterType::CatmulRom),
3 => ResizeAlg::Convolution(FilterType::Lanczos3),
_ => return,
};
fast_resizer.algorithm = resize_alg;
b.iter(|| {
mul_div
.multiply_alpha(&src_view, &mut premultiplied_src_image.dst_view())
.unwrap();
fast_resizer.resize(&premultiplied_src_image.src_view(), &mut dst_view);
mul_div.divide_alpha_inplace(&mut dst_view).unwrap();
})
},
);
}
group.finish();
}
criterion_group!(benches, bench_downscale_rgb, bench_downscale_rgba);
criterion_main!(benches);
+13 -4
View File
@@ -1,9 +1,18 @@
use std::env;
use image::io::Reader;
use image::RgbaImage;
use image::{RgbImage, RgbaImage};
pub fn get_big_rgb_image() -> RgbaImage {
pub fn get_big_rgb_image() -> RgbImage {
let cur_dir = env::current_dir().unwrap();
let img = Reader::open(cur_dir.join("data/nasa-4928x3279.png"))
.unwrap()
.decode()
.unwrap();
img.to_rgb8()
}
pub fn get_big_rgba_image() -> RgbaImage {
let cur_dir = env::current_dir().unwrap();
let img = Reader::open(cur_dir.join("data/nasa-4928x3279.png"))
.unwrap()
@@ -12,11 +21,11 @@ pub fn get_big_rgb_image() -> RgbaImage {
img.to_rgba8()
}
pub fn get_small_rgb_image() -> RgbaImage {
pub fn get_small_rgb_image() -> RgbImage {
let cur_dir = env::current_dir().unwrap();
let img = Reader::open(cur_dir.join("data/nasa-852x567.png"))
.unwrap()
.decode()
.unwrap();
img.to_rgba8()
img.to_rgb8()
}