criterion replaced by glassbench.

This commit is contained in:
Kirill Kuzminykh
2021-07-04 16:33:11 +03:00
parent 89d454e9dc
commit 83cbef093b
9 changed files with 896 additions and 609 deletions
Generated
+575 -215
View File
File diff suppressed because it is too large Load Diff
+7 -2
View File
@@ -18,7 +18,7 @@ thiserror = "1.0.26"
[dev-dependencies]
criterion = "0.3.4"
glassbench = "0.3.0"
image = "0.23.14"
resize = "0.7.0"
rgb = "0.8.25"
@@ -35,7 +35,12 @@ harness = false
[[bench]]
name = "bench_compare"
name = "bench_compare_rgb"
harness = false
[[bench]]
name = "bench_compare_rgba"
harness = false
+23 -23
View File
@@ -21,7 +21,7 @@ Environment:
- RAM: DDR4 3000 MHz
- Ubuntu 20.04 (linux 5.8)
- fast_image_resize = "0.1"
- criterion = "0.3.4"
- glassbench = "0.3.0"
Other Rust libraries used to compare of resizing speed:
- image = "0.23.14" (https://crates.io/crates/image)
@@ -40,25 +40,25 @@ Pipeline:
`src_image => resize => dst_image`
- 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.
- Numbers in table is mean duration of image resizing in milliseconds.
| | Nearest | Bilinear | CatmullRom | Lanczos3 |
|------------|:-------:|:--------:|:----------:|:--------:|
| image | 105.38 | 204.21 | 301.58 | 399.52 |
| resize | 16.223 | 72.447 | 132.64 | 193.26 |
| fir rust | 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 |
| image | 106.841 | 205.303 | 302.171 | 400.717 |
| resize | 16.077 | 72.027 | 132.17 | 192.05 |
| fir rust | 0.477 | 57.038 | 87.254 | 120.589 |
| fir sse4.1 | - | 12.333 | 18.391 | 25.872 |
| fir avx2 | - | 9.369 | 13.371 | 19.002 |
Compiled with `rustflags = ["-C", "target-cpu=native"]`
| | Nearest | Bilinear | CatmullRom | Lanczos3 |
|------------|:-------:|:--------:|:----------:|:--------:|
| image | 91.498 | 183.47 | 282.34 | 386.74 |
| resize | 15.752 | 63.137 | 116.45 | 169.73 |
| fir rust | 0.467 | 58.133 | 65.575 | 89.721 |
| fir sse4.1 | - | 11.567 | 16.566 | 23.859 |
| fir avx2 | - | 8.746 | 11.818 | 17.253 |
| image | 91.607 | 184.2 | 280.471 | 382.259 |
| resize | 15.884 | 62.297 | 115.057 | 168.398 |
| fir rust | 0.473 | 56.827 | 62.832 | 84.949 |
| fir sse4.1 | - | 11.561 | 16.621 | 23.75 |
| fir avx2 | - | 8.747 | 11.873 | 17.31 |
### Resize RGBA image 4928x3279 => 852x567
@@ -67,25 +67,25 @@ Pipeline:
`src_image => multiply by alpha => resize => divide by alpha => dst_image`
- 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.
- Numbers in table is mean duration 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 rust | 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 |
| image | 103.377 | 209.701 | 318.407 | 428.659 |
| resize | 20.121 | 88.308 | 161.366 | 234.437 |
| fir rust | 13.742 | 70.499 | 100.809 | 133.927 |
| fir sse4.1 | 12.031 | 23.732 | 30.216 | 37.862 |
| fir avx2 | 6.894 | 15.442 | 18.875 | 24.157 |
Compiled with `rustflags = ["-C", "target-cpu=native"]`
| | Nearest | Bilinear | CatmullRom | Lanczos3 |
|------------|:-------:|:--------:|:----------:|:--------:|
| image | 97.782 | 246.27 | 403.20 | 568.91 |
| resize | 24.282 | 86.244 | 151.41 | 217.74 |
| fir rust | 9.968 | 67.628 | 74.96 | 99.376 |
| fir sse4.1 | 7.926 | 19.017 | 24.06 | 31.323 |
| fir avx2 | 6.924 | 15.312 | 18.266 | 23.703 |
| image | 91.512 | 186.247 | 289.125 | 399.234 |
| resize | 20.377 | 74.147 | 139.552 | 205.352 |
| fir rust | 9.944 | 65.808 | 72.315 | 94.223 |
| fir sse4.1 | 7.838 | 18.97 | 24.053 | 31.164 |
| fir avx2 | 6.866 | 15.158 | 18.259 | 23.687 |
## Examples of code
+23 -23
View File
@@ -1,7 +1,8 @@
use criterion::{criterion_group, criterion_main, Criterion};
use std::num::NonZeroU32;
use glassbench::*;
use fast_image_resize::{CpuExtensions, ImageData, MulDiv, PixelType};
use std::num::NonZeroU32;
const fn p(r: u8, g: u8, b: u8, a: u8) -> u32 {
u32::from_le_bytes([r, g, b, a])
@@ -22,7 +23,7 @@ fn get_src_image(width: NonZeroU32, height: NonZeroU32, pixel: u32) -> ImageData
ImageData::new(width, height, buffer, PixelType::U8x4).unwrap()
}
fn multiplies_alpha_avx2(c: &mut Criterion) {
fn multiplies_alpha_avx2(bench: &mut Bench) {
let width = NonZeroU32::new(4096).unwrap();
let height = NonZeroU32::new(2048).unwrap();
let src_data = get_src_image(width, height, p(255, 128, 0, 128));
@@ -34,8 +35,8 @@ fn multiplies_alpha_avx2(c: &mut Criterion) {
alpha_mul_div.set_cpu_extensions(CpuExtensions::Avx2);
}
c.bench_function("Multiplies alpha AVX2", |b| {
b.iter(|| {
bench.task("Multiplies alpha AVX2", |task| {
task.iter(|| {
alpha_mul_div
.multiply_alpha(&src_view, &mut dst_view)
.unwrap();
@@ -43,7 +44,7 @@ fn multiplies_alpha_avx2(c: &mut Criterion) {
});
}
fn multiplies_alpha_sse2(c: &mut Criterion) {
fn multiplies_alpha_sse2(bench: &mut Bench) {
let width = NonZeroU32::new(4096).unwrap();
let height = NonZeroU32::new(2048).unwrap();
let src_data = get_src_image(width, height, p(255, 128, 0, 128));
@@ -55,8 +56,8 @@ fn multiplies_alpha_sse2(c: &mut Criterion) {
alpha_mul_div.set_cpu_extensions(CpuExtensions::Sse2);
}
c.bench_function("Multiplies alpha SSE2", |b| {
b.iter(|| {
bench.task("Multiplies alpha SSE2", |task| {
task.iter(|| {
alpha_mul_div
.multiply_alpha(&src_view, &mut dst_view)
.unwrap();
@@ -64,7 +65,7 @@ fn multiplies_alpha_sse2(c: &mut Criterion) {
});
}
fn multiplies_alpha_native(c: &mut Criterion) {
fn multiplies_alpha_native(bench: &mut Bench) {
let width = NonZeroU32::new(4096).unwrap();
let height = NonZeroU32::new(2048).unwrap();
let src_data = get_src_image(width, height, p(255, 128, 0, 128));
@@ -76,8 +77,8 @@ fn multiplies_alpha_native(c: &mut Criterion) {
alpha_mul_div.set_cpu_extensions(CpuExtensions::None);
}
c.bench_function("Multiplies alpha native", |b| {
b.iter(|| {
bench.task("Multiplies alpha native", |task| {
task.iter(|| {
alpha_mul_div
.multiply_alpha(&src_view, &mut dst_view)
.unwrap();
@@ -85,7 +86,7 @@ fn multiplies_alpha_native(c: &mut Criterion) {
});
}
fn divides_alpha_avx2(c: &mut Criterion) {
fn divides_alpha_avx2(bench: &mut Bench) {
let width = NonZeroU32::new(4096).unwrap();
let height = NonZeroU32::new(2048).unwrap();
let src_data = get_src_image(width, height, p(128, 64, 0, 128));
@@ -97,8 +98,8 @@ fn divides_alpha_avx2(c: &mut Criterion) {
alpha_mul_div.set_cpu_extensions(CpuExtensions::Avx2);
}
c.bench_function("Divides alpha AVX2", |b| {
b.iter(|| {
bench.task("Divides alpha AVX2", |task| {
task.iter(|| {
alpha_mul_div
.divide_alpha(&src_view, &mut dst_view)
.unwrap();
@@ -106,7 +107,7 @@ fn divides_alpha_avx2(c: &mut Criterion) {
});
}
fn divides_alpha_sse2(c: &mut Criterion) {
fn divides_alpha_sse2(bench: &mut Bench) {
let width = NonZeroU32::new(4096).unwrap();
let height = NonZeroU32::new(2048).unwrap();
let src_data = get_src_image(width, height, p(128, 64, 0, 128));
@@ -118,8 +119,8 @@ fn divides_alpha_sse2(c: &mut Criterion) {
alpha_mul_div.set_cpu_extensions(CpuExtensions::Sse2);
}
c.bench_function("Divides alpha SSE2", |b| {
b.iter(|| {
bench.task("Divides alpha SSE2", |task| {
task.iter(|| {
alpha_mul_div
.divide_alpha(&src_view, &mut dst_view)
.unwrap();
@@ -127,7 +128,7 @@ fn divides_alpha_sse2(c: &mut Criterion) {
});
}
fn divides_alpha_native(c: &mut Criterion) {
fn divides_alpha_native(bench: &mut Bench) {
let width = NonZeroU32::new(4096).unwrap();
let height = NonZeroU32::new(2048).unwrap();
let src_data = get_src_image(width, height, p(128, 64, 0, 128));
@@ -139,8 +140,8 @@ fn divides_alpha_native(c: &mut Criterion) {
alpha_mul_div.set_cpu_extensions(CpuExtensions::None);
}
c.bench_function("Divides alpha native", |b| {
b.iter(|| {
bench.task("Divides alpha native", |task| {
task.iter(|| {
alpha_mul_div
.divide_alpha(&src_view, &mut dst_view)
.unwrap();
@@ -148,8 +149,8 @@ fn divides_alpha_native(c: &mut Criterion) {
});
}
criterion_group!(
benches,
glassbench!(
"Alpha",
multiplies_alpha_avx2,
multiplies_alpha_sse2,
multiplies_alpha_native,
@@ -157,4 +158,3 @@ criterion_group!(
divides_alpha_sse2,
divides_alpha_native,
);
criterion_main!(benches);
-315
View File
@@ -1,315 +0,0 @@
use std::num::NonZeroU32;
use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion};
use image::imageops;
use resize::px::RGBA;
use resize::Pixel::{RGB8, RGBA8};
use rgb::{FromSlice, RGB};
use fast_image_resize::{CpuExtensions, FilterType, PixelType, ResizeAlg, Resizer};
use fast_image_resize::{ImageData, MulDiv};
mod utils;
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 RGB (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_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),
&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,
RGB8,
filter,
)
.unwrap();
b.iter(|| {
resizer.resize(resize_src_image, &mut dst).unwrap();
})
},
);
// 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_rgba_image.as_raw(),
PixelType::U8x4,
)
.unwrap();
let src_view = src_image_data.src_view();
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);
unsafe {
fast_resizer.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(|| {
fast_resizer.resize(&src_view, &mut dst_view);
})
},
);
let mut fast_resizer = Resizer::new(ResizeAlg::Nearest);
unsafe {
fast_resizer.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(|| {
fast_resizer.resize(&src_view, &mut dst_view);
})
},
);
let mut fast_resizer = Resizer::new(ResizeAlg::Nearest);
unsafe {
fast_resizer.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(|| {
fast_resizer.resize(&src_view, &mut dst_view);
})
},
);
}
group.finish();
}
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);
+114
View File
@@ -0,0 +1,114 @@
use std::num::NonZeroU32;
use glassbench::*;
use image::imageops;
use resize::Pixel::RGB8;
use rgb::{FromSlice, RGB};
use fast_image_resize::ImageData;
use fast_image_resize::{CpuExtensions, FilterType, PixelType, ResizeAlg, Resizer};
mod utils;
pub fn bench_downscale_rgb(bench: &mut Bench) {
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 RGB (4928x3279 => 852x567)");
let alg_names = ["nearest", "triangle", "catmulrom", "lanczos3"];
// image crate
// https://crates.io/crates/image
for alg_name in alg_names {
let filter = match alg_name {
"nearest" => imageops::Nearest,
"triangle" => imageops::Triangle,
"catmulrom" => imageops::CatmullRom,
"lanczos3" => imageops::Lanczos3,
_ => continue,
};
bench.task(format!("image - {}", alg_name), |task| {
task.iter(|| {
imageops::resize(&src_image, new_width.get(), new_height.get(), filter);
})
});
}
// resize crate
// https://crates.io/crates/resize
for alg_name in alg_names {
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];
bench.task(format!("resize - {}", alg_name), |task| {
let filter = match alg_name {
"nearest" => resize::Type::Point,
"triangle" => resize::Type::Triangle,
"catmulrom" => resize::Type::Catrom,
"lanczos3" => resize::Type::Lanczos3,
_ => return,
};
let mut resize = resize::new(
src_image.width() as usize,
src_image.height() as usize,
new_width.get() as usize,
new_height.get() as usize,
RGB8,
filter,
)
.unwrap();
task.iter(|| {
resize.resize(resize_src_image, &mut dst).unwrap();
})
});
}
// fast_image_resize crate;
for cpu_ext in [
CpuExtensions::None,
CpuExtensions::Sse4_1,
CpuExtensions::Avx2,
] {
let ext_name = match cpu_ext {
CpuExtensions::None => "rust",
CpuExtensions::Sse4_1 => "sse4.1",
CpuExtensions::Avx2 => "avx2",
_ => continue,
};
for alg_name in alg_names {
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_rgba_image.as_raw(),
PixelType::U8x4,
)
.unwrap();
let src_view = src_image_data.src_view();
let mut dst_image = ImageData::new_owned(new_width, new_height, PixelType::U8x4);
let mut dst_view = dst_image.dst_view();
let resize_alg = match alg_name {
"nearest" => ResizeAlg::Nearest,
"triangle" => ResizeAlg::Convolution(FilterType::Bilinear),
"catmulrom" => ResizeAlg::Convolution(FilterType::CatmulRom),
"lanczos3" => ResizeAlg::Convolution(FilterType::Lanczos3),
_ => return,
};
let mut fast_resizer = Resizer::new(resize_alg);
unsafe {
fast_resizer.reset_internal_buffers();
fast_resizer.set_cpu_extensions(cpu_ext);
}
bench.task(format!("fir {} - {}", ext_name, alg_name), |task| {
task.iter(|| {
fast_resizer.resize(&src_view, &mut dst_view);
})
});
}
}
}
glassbench!("Compare", bench_downscale_rgb,);
+125
View File
@@ -0,0 +1,125 @@
use std::num::NonZeroU32;
use glassbench::*;
use image::imageops;
use resize::px::RGBA;
use resize::Pixel::RGBA8;
use rgb::FromSlice;
use fast_image_resize::{CpuExtensions, FilterType, PixelType, ResizeAlg, Resizer};
use fast_image_resize::{ImageData, MulDiv};
mod utils;
pub fn bench_downscale_rgba(bench: &mut Bench) {
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 RGB (4928x3279 => 852x567)");
let alg_names = ["nearest", "triangle", "catmulrom", "lanczos3"];
// image crate
// https://crates.io/crates/image
for alg_name in alg_names {
let filter = match alg_name {
"nearest" => imageops::Nearest,
"triangle" => imageops::Triangle,
"catmulrom" => imageops::CatmullRom,
"lanczos3" => imageops::Lanczos3,
_ => continue,
};
bench.task(format!("image - {}", alg_name), |task| {
task.iter(|| {
imageops::resize(&src_image, new_width.get(), new_height.get(), filter);
})
});
}
// resize crate
// https://crates.io/crates/resize
for alg_name in alg_names {
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];
bench.task(format!("resize - {}", alg_name), |task| {
let filter = match alg_name {
"nearest" => resize::Type::Point,
"triangle" => resize::Type::Triangle,
"catmulrom" => resize::Type::Catrom,
"lanczos3" => resize::Type::Lanczos3,
_ => return,
};
let mut resize = 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();
task.iter(|| {
resize.resize(resize_src_image, &mut dst).unwrap();
})
});
}
// fast_image_resize crate;
for cpu_ext in [
CpuExtensions::None,
CpuExtensions::Sse4_1,
CpuExtensions::Avx2,
] {
let ext_name = match cpu_ext {
CpuExtensions::None => "rust",
CpuExtensions::Sse4_1 => "sse4.1",
CpuExtensions::Avx2 => "avx2",
_ => continue,
};
for alg_name in alg_names {
let resize_alg = match alg_name {
"nearest" => ResizeAlg::Nearest,
"triangle" => ResizeAlg::Convolution(FilterType::Bilinear),
"catmulrom" => ResizeAlg::Convolution(FilterType::CatmulRom),
"lanczos3" => ResizeAlg::Convolution(FilterType::Lanczos3),
_ => return,
};
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 mul_div = MulDiv::default();
let mut fast_resizer = Resizer::new(resize_alg);
unsafe {
fast_resizer.reset_internal_buffers();
fast_resizer.set_cpu_extensions(cpu_ext);
mul_div.set_cpu_extensions(cpu_ext);
}
bench.task(format!("fir {} - {}", ext_name, alg_name), |task| {
task.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();
})
});
}
}
}
glassbench!("Compare", bench_downscale_rgba,);
+27 -29
View File
@@ -1,6 +1,6 @@
use std::num::NonZeroU32;
use criterion::{criterion_group, criterion_main, Criterion};
use glassbench::*;
use fast_image_resize::ImageData;
use fast_image_resize::{CpuExtensions, FilterType, PixelType, ResizeAlg, Resizer};
@@ -14,7 +14,7 @@ const NEW_BIG_WIDTH: u32 = 4928;
const NEW_BIG_HEIGHT: u32 = 3279;
fn get_big_source_image() -> ImageData<Vec<u8>> {
let img = utils::get_big_rgb_image();
let img = utils::get_big_rgba_image();
let width = img.width();
let height = img.height();
let buf = img.as_raw().clone();
@@ -28,7 +28,7 @@ fn get_big_source_image() -> ImageData<Vec<u8>> {
}
fn get_small_source_image() -> ImageData<Vec<u8>> {
let img = utils::get_small_rgb_image();
let img = utils::get_small_rgba_image();
let width = img.width();
let height = img.height();
let buf = img.as_raw().clone();
@@ -41,7 +41,7 @@ fn get_small_source_image() -> ImageData<Vec<u8>> {
.unwrap()
}
fn downscale_nearest_wo_simd_bench(c: &mut Criterion) {
fn nearest_wo_simd_bench(bench: &mut Bench) {
let image = get_big_source_image();
let mut res_image = ImageData::new_owned(
NonZeroU32::new(NEW_WIDTH).unwrap(),
@@ -54,14 +54,14 @@ fn downscale_nearest_wo_simd_bench(c: &mut Criterion) {
unsafe {
resizer.set_cpu_extensions(CpuExtensions::None);
}
c.bench_function("Downscale nearest wo SIMD", |b| {
b.iter(|| {
bench.task("nearest wo SIMD", |task| {
task.iter(|| {
resizer.resize(&src_image, &mut dst_image);
})
});
}
fn downscale_lanczos3_wo_simd_bench(c: &mut Criterion) {
fn lanczos3_wo_simd_bench(bench: &mut Bench) {
let image = get_big_source_image();
let mut res_image = ImageData::new_owned(
NonZeroU32::new(NEW_WIDTH).unwrap(),
@@ -74,14 +74,14 @@ fn downscale_lanczos3_wo_simd_bench(c: &mut Criterion) {
unsafe {
resizer.set_cpu_extensions(CpuExtensions::None);
}
c.bench_function("Downscale lanczos3 wo SIMD", |b| {
b.iter(|| {
bench.task("lanczos3 wo SIMD", |task| {
task.iter(|| {
resizer.resize(&src_image, &mut dst_image);
})
});
}
fn sse4_lanczos3_bench(c: &mut Criterion) {
fn sse4_lanczos3_bench(bench: &mut Bench) {
let image = get_big_source_image();
let mut res_image = ImageData::new_owned(
NonZeroU32::new(NEW_WIDTH).unwrap(),
@@ -94,14 +94,14 @@ fn sse4_lanczos3_bench(c: &mut Criterion) {
unsafe {
resizer.set_cpu_extensions(CpuExtensions::Sse4_1);
}
c.bench_function("sse4 lanczos3", |b| {
b.iter(|| {
bench.task("sse4 lanczos3", |task| {
task.iter(|| {
resizer.resize(&src_image, &mut dst_image);
})
});
}
fn avx2_lanczos3_bench(c: &mut Criterion) {
fn avx2_lanczos3_bench(bench: &mut Bench) {
let image = get_big_source_image();
let mut res_image = ImageData::new_owned(
NonZeroU32::new(NEW_WIDTH).unwrap(),
@@ -114,14 +114,14 @@ fn avx2_lanczos3_bench(c: &mut Criterion) {
unsafe {
resizer.set_cpu_extensions(CpuExtensions::Avx2);
}
c.bench_function("avx2 lanczos3", |b| {
b.iter(|| {
bench.task("avx2 lanczos3", |task| {
task.iter(|| {
resizer.resize(&src_image, &mut dst_image);
})
});
}
fn avx2_supersampling_lanczos3_bench(c: &mut Criterion) {
fn avx2_supersampling_lanczos3_bench(bench: &mut Bench) {
let image = get_big_source_image();
let mut res_image = ImageData::new_owned(
NonZeroU32::new(NEW_WIDTH).unwrap(),
@@ -134,14 +134,14 @@ fn avx2_supersampling_lanczos3_bench(c: &mut Criterion) {
unsafe {
resizer.set_cpu_extensions(CpuExtensions::Avx2);
}
c.bench_function("avx2 supersampling lanczos3", |b| {
b.iter(|| {
bench.task("avx2 supersampling lanczos3", |task| {
task.iter(|| {
resizer.resize(&src_image, &mut dst_image);
})
});
}
fn avx2_lanczos3_upscale_bench(c: &mut Criterion) {
fn avx2_lanczos3_upscale_bench(bench: &mut Bench) {
let image = get_small_source_image();
let mut res_image = ImageData::new_owned(
NonZeroU32::new(NEW_BIG_WIDTH).unwrap(),
@@ -154,21 +154,19 @@ fn avx2_lanczos3_upscale_bench(c: &mut Criterion) {
unsafe {
resizer.set_cpu_extensions(CpuExtensions::Avx2);
}
c.bench_function("avx2 lanczos3 upscale", |b| {
b.iter(|| {
bench.task("avx2 lanczos3 upscale", |task| {
task.iter(|| {
resizer.resize(&src_image, &mut dst_image);
})
});
}
criterion_group!(
benches,
// downscale_nearest_wo_simd_bench,
downscale_lanczos3_wo_simd_bench,
// resize_lanczos3_bench,
glassbench!(
"Resize",
nearest_wo_simd_bench,
lanczos3_wo_simd_bench,
sse4_lanczos3_bench,
avx2_lanczos3_bench,
// avx2_supersampling_lanczos3_bench,
// avx2_lanczos3_upscale_bench,
avx2_supersampling_lanczos3_bench,
avx2_lanczos3_upscale_bench,
);
criterion_main!(benches);
+2 -2
View File
@@ -21,11 +21,11 @@ pub fn get_big_rgba_image() -> RgbaImage {
img.to_rgba8()
}
pub fn get_small_rgb_image() -> RgbImage {
pub fn get_small_rgba_image() -> RgbaImage {
let cur_dir = env::current_dir().unwrap();
let img = Reader::open(cur_dir.join("data/nasa-852x567.png"))
.unwrap()
.decode()
.unwrap();
img.to_rgb8()
img.to_rgba8()
}