mirror of
https://github.com/Cykooz/fast_image_resize.git
synced 2026-10-08 01:11:09 +00:00
- Benchmark framework glassbench replaced by criterion.
- Added report with results of benchmarks for `wasm32-wasi` target.
This commit is contained in:
@@ -1,3 +1,10 @@
|
||||
## [Unreleased] - ReleaseDate
|
||||
|
||||
## Benchmarks
|
||||
|
||||
- Benchmark framework `glassbench` replaced by `criterion`.
|
||||
- Added report with results of benchmarks for `wasm32-wasi` target.
|
||||
|
||||
## [2.4.0] - 2022-12-11
|
||||
|
||||
### Crate
|
||||
|
||||
Generated
+215
-793
File diff suppressed because it is too large
Load Diff
+11
-2
@@ -28,13 +28,22 @@ for_test = []
|
||||
|
||||
[dev-dependencies]
|
||||
fast_image_resize = { path = ".", features = ["for_test"] }
|
||||
glassbench = "0.3.3"
|
||||
image = "0.24.5"
|
||||
resize = "0.7.4"
|
||||
rgb = "0.8.34"
|
||||
png = "0.17.7"
|
||||
nix = { version = "0.26.1", default-features = false, features = ["sched"] }
|
||||
testing = { path = "testing" }
|
||||
serde = { version = "1.0", features = ["serde_derive"] }
|
||||
serde_json = "1.0"
|
||||
walkdir = "2"
|
||||
itertools = "0.10.5"
|
||||
|
||||
[target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies]
|
||||
criterion = { version = "0.4.0", default-features = false, features = ["cargo_bench_support", "rayon"] }
|
||||
nix = { version = "0.26.1", default-features = false, features = ["sched"] }
|
||||
|
||||
[target.'cfg(target_arch = "wasm32")'.dev-dependencies]
|
||||
criterion = { version = "0.4.0", default-features = false, features = ["cargo_bench_support"] }
|
||||
|
||||
|
||||
[[bench]]
|
||||
|
||||
@@ -41,10 +41,10 @@ In addition, the crate contains functions `create_gamma_22_mapper()`
|
||||
and `create_srgb_mapper()` to create instance of `PixelComponentMapper`
|
||||
that converts images from sRGB or gamma 2.2 into linear colorspace and back.
|
||||
|
||||
## Some benchmarks
|
||||
## Some benchmarks for x86_64
|
||||
|
||||
- [All x86-64 benchmarks.](https://github.com/Cykooz/fast_image_resize/blob/main/benchmarks_x86-64.md)
|
||||
- [All arm64 benchmarks.](https://github.com/Cykooz/fast_image_resize/blob/main/benchmarks_arm64.md)
|
||||
- [All x86_64 benchmarks.](https://github.com/Cykooz/fast_image_resize/blob/main/benchmarks-x86_64.md)
|
||||
- [All arm64 benchmarks.](https://github.com/Cykooz/fast_image_resize/blob/main/benchmarks-arm64.md)
|
||||
|
||||
Rust libraries used to compare of resizing speed:
|
||||
|
||||
@@ -60,6 +60,7 @@ Pipeline:
|
||||
- Source image [nasa-4928x3279.png](https://github.com/Cykooz/fast_image_resize/blob/main/data/nasa-4928x3279.png)
|
||||
- Numbers in table is mean duration of image resizing in milliseconds.
|
||||
|
||||
[comment]: <> (bench_compare_rgb start)
|
||||
| | Nearest | Bilinear | CatmullRom | Lanczos3 |
|
||||
|------------|:-------:|:--------:|:----------:|:--------:|
|
||||
| image | 20.66 | 82.74 | 141.56 | 199.96 |
|
||||
@@ -67,6 +68,7 @@ Pipeline:
|
||||
| fir rust | 0.28 | 39.57 | 67.00 | 98.50 |
|
||||
| fir sse4.1 | 0.28 | 9.63 | 14.13 | 19.84 |
|
||||
| fir avx2 | 0.28 | 7.73 | 9.67 | 14.66 |
|
||||
[comment]: <> (bench_compare_rgb end)
|
||||
|
||||
### Resize RGBA8 image (U8x4) 4928x3279 => 852x567
|
||||
|
||||
@@ -79,12 +81,14 @@ Pipeline:
|
||||
- Numbers in table is mean duration of image resizing in milliseconds.
|
||||
- The `image` crate does not support multiplying and dividing by alpha channel.
|
||||
|
||||
[comment]: <> (bench_compare_rgba start)
|
||||
| | Nearest | Bilinear | CatmullRom | Lanczos3 |
|
||||
|------------|:-------:|:--------:|:----------:|:--------:|
|
||||
| resize | - | 65.74 | 130.18 | 194.13 |
|
||||
| fir rust | 0.19 | 35.61 | 52.50 | 75.76 |
|
||||
| fir sse4.1 | 0.19 | 13.19 | 17.25 | 22.62 |
|
||||
| fir avx2 | 0.19 | 9.57 | 11.97 | 16.37 |
|
||||
[comment]: <> (bench_compare_rgba end)
|
||||
|
||||
### Resize L8 image (U8) 4928x3279 => 852x567
|
||||
|
||||
@@ -96,6 +100,7 @@ Pipeline:
|
||||
has converted into grayscale image with one byte per pixel.
|
||||
- Numbers in table is mean duration of image resizing in milliseconds.
|
||||
|
||||
[comment]: <> (bench_compare_l start)
|
||||
| | Nearest | Bilinear | CatmullRom | Lanczos3 |
|
||||
|------------|:-------:|:--------:|:----------:|:--------:|
|
||||
| image | 16.97 | 48.47 | 77.55 | 107.48 |
|
||||
@@ -103,6 +108,7 @@ Pipeline:
|
||||
| fir rust | 0.15 | 13.44 | 14.73 | 22.58 |
|
||||
| fir sse4.1 | 0.15 | 4.99 | 5.28 | 8.05 |
|
||||
| fir avx2 | 0.15 | 7.09 | 5.18 | 8.60 |
|
||||
[comment]: <> (bench_compare_l end)
|
||||
|
||||
## Examples
|
||||
|
||||
|
||||
+61
-42
@@ -1,7 +1,5 @@
|
||||
use std::num::NonZeroU32;
|
||||
|
||||
use glassbench::*;
|
||||
|
||||
use fast_image_resize::MulDiv;
|
||||
use fast_image_resize::PixelType;
|
||||
use fast_image_resize::{CpuExtensions, Image};
|
||||
@@ -23,7 +21,13 @@ fn get_src_image(
|
||||
Image::from_vec_u8(width, height, buffer, pixel_type).unwrap()
|
||||
}
|
||||
|
||||
fn multiplies_alpha(bench: &mut Bench, pixel_type: PixelType, cpu_extensions: CpuExtensions) {
|
||||
fn multiplies_alpha(
|
||||
bench_group: &mut utils::BenchGroup,
|
||||
pixel_type: PixelType,
|
||||
cpu_extensions: CpuExtensions,
|
||||
ext_name: &str,
|
||||
) {
|
||||
let sample_size = 100;
|
||||
let width = NonZeroU32::new(4096).unwrap();
|
||||
let height = NonZeroU32::new(2048).unwrap();
|
||||
let pixel: &[u8] = match pixel_type {
|
||||
@@ -42,10 +46,13 @@ fn multiplies_alpha(bench: &mut Bench, pixel_type: PixelType, cpu_extensions: Cp
|
||||
alpha_mul_div.set_cpu_extensions(cpu_extensions);
|
||||
}
|
||||
|
||||
bench.task(
|
||||
format!("Multiplies alpha {:?} {:?}", pixel_type, cpu_extensions),
|
||||
|task| {
|
||||
task.iter(|| {
|
||||
utils::bench(
|
||||
bench_group,
|
||||
sample_size,
|
||||
format!("Multiplies alpha {:?}", pixel_type),
|
||||
ext_name,
|
||||
|bencher| {
|
||||
bencher.iter(|| {
|
||||
alpha_mul_div
|
||||
.multiply_alpha(&src_view, &mut dst_view)
|
||||
.unwrap();
|
||||
@@ -53,22 +60,29 @@ fn multiplies_alpha(bench: &mut Bench, pixel_type: PixelType, cpu_extensions: Cp
|
||||
},
|
||||
);
|
||||
|
||||
bench.task(
|
||||
format!(
|
||||
"Multiplies alpha inplace {:?} {:?}",
|
||||
pixel_type, cpu_extensions
|
||||
),
|
||||
|task| {
|
||||
let mut data = get_src_image(width, height, pixel_type, pixel);
|
||||
let mut view = data.view_mut();
|
||||
task.iter(|| {
|
||||
let src_image = get_src_image(width, height, pixel_type, pixel);
|
||||
utils::bench(
|
||||
bench_group,
|
||||
sample_size,
|
||||
format!("Multiplies alpha inplace {:?}", pixel_type),
|
||||
ext_name,
|
||||
|bencher| {
|
||||
let mut image = src_image.copy();
|
||||
let mut view = image.view_mut();
|
||||
bencher.iter(|| {
|
||||
alpha_mul_div.multiply_alpha_inplace(&mut view).unwrap();
|
||||
})
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
fn divides_alpha(bench: &mut Bench, pixel_type: PixelType, cpu_extensions: CpuExtensions) {
|
||||
fn divides_alpha(
|
||||
bench_group: &mut utils::BenchGroup,
|
||||
pixel_type: PixelType,
|
||||
cpu_extensions: CpuExtensions,
|
||||
ext_name: &str,
|
||||
) {
|
||||
let sample_size = 100;
|
||||
let width = NonZeroU32::new(4095).unwrap();
|
||||
let height = NonZeroU32::new(2048).unwrap();
|
||||
let pixel: &[u8] = match pixel_type {
|
||||
@@ -87,10 +101,13 @@ fn divides_alpha(bench: &mut Bench, pixel_type: PixelType, cpu_extensions: CpuEx
|
||||
alpha_mul_div.set_cpu_extensions(cpu_extensions);
|
||||
}
|
||||
|
||||
bench.task(
|
||||
format!("Divides alpha {:?} {:?}", pixel_type, cpu_extensions),
|
||||
|task| {
|
||||
task.iter(|| {
|
||||
utils::bench(
|
||||
bench_group,
|
||||
sample_size,
|
||||
format!("Divides alpha {:?}", pixel_type),
|
||||
ext_name,
|
||||
|bencher| {
|
||||
bencher.iter(|| {
|
||||
alpha_mul_div
|
||||
.divide_alpha(&src_view, &mut dst_view)
|
||||
.unwrap();
|
||||
@@ -98,50 +115,52 @@ fn divides_alpha(bench: &mut Bench, pixel_type: PixelType, cpu_extensions: CpuEx
|
||||
},
|
||||
);
|
||||
|
||||
bench.task(
|
||||
format!(
|
||||
"Divides alpha inplace {:?} {:?}",
|
||||
pixel_type, cpu_extensions
|
||||
),
|
||||
|task| {
|
||||
let mut data = get_src_image(width, height, pixel_type, pixel);
|
||||
let mut view = data.view_mut();
|
||||
task.iter(|| {
|
||||
let src_image = get_src_image(width, height, pixel_type, pixel);
|
||||
utils::bench(
|
||||
bench_group,
|
||||
sample_size,
|
||||
format!("Divides alpha inplace {:?}", pixel_type),
|
||||
ext_name,
|
||||
|bencher| {
|
||||
let mut image = src_image.copy();
|
||||
let mut view = image.view_mut();
|
||||
bencher.iter(|| {
|
||||
alpha_mul_div.divide_alpha_inplace(&mut view).unwrap();
|
||||
})
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
fn bench_alpha(bench: &mut Bench) {
|
||||
fn bench_alpha(bench_group: &mut utils::BenchGroup) {
|
||||
let pixel_types = [
|
||||
PixelType::U8x2,
|
||||
PixelType::U8x4,
|
||||
PixelType::U16x2,
|
||||
PixelType::U16x4,
|
||||
];
|
||||
let mut cpu_extensions = vec![CpuExtensions::None];
|
||||
let mut cpu_ext_and_name = vec![(CpuExtensions::None, "rust")];
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
{
|
||||
cpu_extensions.push(CpuExtensions::Sse4_1);
|
||||
cpu_extensions.push(CpuExtensions::Avx2);
|
||||
cpu_ext_and_name.push((CpuExtensions::Sse4_1, "sse4.1"));
|
||||
cpu_ext_and_name.push((CpuExtensions::Avx2, "avx2"));
|
||||
}
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
{
|
||||
cpu_extensions.push(CpuExtensions::Neon);
|
||||
cpu_ext_and_name.push((CpuExtensions::Neon, "neon"));
|
||||
}
|
||||
for pixel_type in pixel_types {
|
||||
for &extensions in cpu_extensions.iter() {
|
||||
println!("Mul {:?} {:?}", pixel_type, extensions);
|
||||
multiplies_alpha(bench, pixel_type, extensions);
|
||||
for &(cpu_ext, ext_name) in cpu_ext_and_name.iter() {
|
||||
multiplies_alpha(bench_group, pixel_type, cpu_ext, ext_name);
|
||||
}
|
||||
}
|
||||
for pixel_type in pixel_types {
|
||||
for &extensions in cpu_extensions.iter() {
|
||||
println!("Div {:?} {:?}", pixel_type, extensions);
|
||||
divides_alpha(bench, pixel_type, extensions);
|
||||
for &(cpu_ext, ext_name) in cpu_ext_and_name.iter() {
|
||||
divides_alpha(bench_group, pixel_type, cpu_ext, ext_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bench_main!("Bench Alpha", bench_alpha,);
|
||||
fn main() {
|
||||
let res = utils::run_bench(bench_alpha, "Bench Alpha");
|
||||
println!("{}", utils::build_md_table(&res));
|
||||
}
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
use glassbench::*;
|
||||
|
||||
use fast_image_resize::pixels::U8x3;
|
||||
use fast_image_resize::{create_srgb_mapper, Image};
|
||||
use testing::PixelTestingExt;
|
||||
|
||||
mod utils;
|
||||
|
||||
pub fn bench_color_mapper(bench: &mut Bench) {
|
||||
pub fn bench_color_mapper(bench_group: &mut utils::BenchGroup) {
|
||||
let src_image = U8x3::load_big_src_image();
|
||||
let mut dst_image = Image::new(
|
||||
src_image.width(),
|
||||
@@ -16,11 +14,13 @@ pub fn bench_color_mapper(bench: &mut Bench) {
|
||||
let src_view = src_image.view();
|
||||
let mut dst_view = dst_image.view_mut();
|
||||
let mapper = create_srgb_mapper();
|
||||
bench.task("SRGB U8x3 => RGB U8x3", |task| {
|
||||
task.iter(|| {
|
||||
bench_group.bench_function("SRGB U8x3 => RGB U8x3", |bencher| {
|
||||
bencher.iter(|| {
|
||||
mapper.forward_map(&src_view, &mut dst_view).unwrap();
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
bench_main!("Bench color mappers", bench_color_mapper,);
|
||||
fn main() {
|
||||
utils::run_bench(bench_color_mapper, "Color mapper");
|
||||
}
|
||||
|
||||
+16
-107
@@ -1,117 +1,26 @@
|
||||
use std::num::NonZeroU32;
|
||||
use std::thread::sleep;
|
||||
use std::time::Duration;
|
||||
|
||||
use glassbench::*;
|
||||
use image::imageops;
|
||||
use resize::Pixel::Gray8;
|
||||
use rgb::alt::Gray;
|
||||
use rgb::FromSlice;
|
||||
|
||||
use fast_image_resize::pixels::U8;
|
||||
use fast_image_resize::Image;
|
||||
use fast_image_resize::{CpuExtensions, FilterType, ResizeAlg, Resizer};
|
||||
use testing::PixelTestingExt;
|
||||
|
||||
mod utils;
|
||||
|
||||
pub fn bench_downscale_l(bench: &mut Bench) {
|
||||
let src_image = U8::load_big_image().to_luma8();
|
||||
let new_width = NonZeroU32::new(852).unwrap();
|
||||
let new_height = NonZeroU32::new(567).unwrap();
|
||||
|
||||
let alg_names = ["Nearest", "Bilinear", "CatmullRom", "Lanczos3"];
|
||||
|
||||
// image crate
|
||||
// https://crates.io/crates/image
|
||||
for alg_name in alg_names {
|
||||
let filter = match alg_name {
|
||||
"Nearest" => imageops::Nearest,
|
||||
"Bilinear" => imageops::Triangle,
|
||||
"CatmullRom" => 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_gray();
|
||||
let mut dst = vec![Gray(0u8); (new_width.get() * new_height.get()) as usize];
|
||||
bench.task(format!("resize - {}", alg_name), |task| {
|
||||
let filter = match alg_name {
|
||||
"Nearest" => {
|
||||
// resizer doesn't support "nearest" algorithm
|
||||
task.iter(|| sleep(Duration::new(0, 1)));
|
||||
return;
|
||||
}
|
||||
"Bilinear" => resize::Type::Triangle,
|
||||
"CatmullRom" => 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,
|
||||
Gray8,
|
||||
filter,
|
||||
)
|
||||
.unwrap();
|
||||
task.iter(|| {
|
||||
resize.resize(resize_src_image, &mut dst).unwrap();
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// fast_image_resize crate;
|
||||
let mut cpu_ext_and_name = vec![(CpuExtensions::None, "rust")];
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
{
|
||||
cpu_ext_and_name.push((CpuExtensions::Sse4_1, "sse4.1"));
|
||||
cpu_ext_and_name.push((CpuExtensions::Avx2, "avx2"));
|
||||
}
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
{
|
||||
cpu_ext_and_name.push((CpuExtensions::Neon, "neon"));
|
||||
}
|
||||
for (cpu_ext, ext_name) in cpu_ext_and_name {
|
||||
for alg_name in alg_names {
|
||||
let src_image_data = U8::load_big_src_image();
|
||||
let src_view = src_image_data.view();
|
||||
let mut dst_image = Image::new(new_width, new_height, src_view.pixel_type());
|
||||
let mut dst_view = dst_image.view_mut();
|
||||
|
||||
let resize_alg = match alg_name {
|
||||
"Nearest" => ResizeAlg::Nearest,
|
||||
"Bilinear" => ResizeAlg::Convolution(FilterType::Bilinear),
|
||||
"CatmullRom" => ResizeAlg::Convolution(FilterType::CatmullRom),
|
||||
"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).unwrap();
|
||||
})
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
utils::print_md_table(bench);
|
||||
pub fn bench_compare_l(bench_group: &mut utils::BenchGroup) {
|
||||
type P = U8;
|
||||
let src_image = P::load_big_image().to_luma8();
|
||||
utils::image_resize(bench_group, &src_image);
|
||||
utils::resize_resize(
|
||||
bench_group,
|
||||
Gray8,
|
||||
src_image.as_raw().as_gray(),
|
||||
src_image.width(),
|
||||
src_image.height(),
|
||||
);
|
||||
utils::fir_resize::<P>(bench_group);
|
||||
}
|
||||
|
||||
bench_main!("Compare resize of U8 image", bench_downscale_l,);
|
||||
fn main() {
|
||||
let res = utils::run_bench(bench_compare_l, "Compare resize of U8 image");
|
||||
utils::print_and_write_compare_result(&res);
|
||||
}
|
||||
|
||||
+16
-107
@@ -1,117 +1,26 @@
|
||||
use std::num::NonZeroU32;
|
||||
use std::thread::sleep;
|
||||
use std::time::Duration;
|
||||
|
||||
use glassbench::*;
|
||||
use image::imageops;
|
||||
use resize::Pixel::Gray16;
|
||||
use rgb::alt::Gray;
|
||||
use rgb::FromSlice;
|
||||
|
||||
use fast_image_resize::pixels::U16;
|
||||
use fast_image_resize::Image;
|
||||
use fast_image_resize::{CpuExtensions, FilterType, ResizeAlg, Resizer};
|
||||
use testing::PixelTestingExt;
|
||||
|
||||
mod utils;
|
||||
|
||||
pub fn bench_downscale_l16(bench: &mut Bench) {
|
||||
let src_image = U16::load_big_image().to_luma16();
|
||||
let new_width = NonZeroU32::new(852).unwrap();
|
||||
let new_height = NonZeroU32::new(567).unwrap();
|
||||
|
||||
let alg_names = ["Nearest", "Bilinear", "CatmullRom", "Lanczos3"];
|
||||
|
||||
// image crate
|
||||
// https://crates.io/crates/image
|
||||
for alg_name in alg_names {
|
||||
let filter = match alg_name {
|
||||
"Nearest" => imageops::Nearest,
|
||||
"Bilinear" => imageops::Triangle,
|
||||
"CatmullRom" => 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_gray();
|
||||
let mut dst = vec![Gray(0u16); (new_width.get() * new_height.get()) as usize];
|
||||
bench.task(format!("resize - {}", alg_name), |task| {
|
||||
let filter = match alg_name {
|
||||
"Nearest" => {
|
||||
// resizer doesn't support "nearest" algorithm
|
||||
task.iter(|| sleep(Duration::new(0, 1)));
|
||||
return;
|
||||
}
|
||||
"Bilinear" => resize::Type::Triangle,
|
||||
"CatmullRom" => 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,
|
||||
Gray16,
|
||||
filter,
|
||||
)
|
||||
.unwrap();
|
||||
task.iter(|| {
|
||||
resize.resize(resize_src_image, &mut dst).unwrap();
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// fast_image_resize crate;
|
||||
let mut cpu_ext_and_name = vec![(CpuExtensions::None, "rust")];
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
{
|
||||
cpu_ext_and_name.push((CpuExtensions::Sse4_1, "sse4.1"));
|
||||
cpu_ext_and_name.push((CpuExtensions::Avx2, "avx2"));
|
||||
}
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
{
|
||||
cpu_ext_and_name.push((CpuExtensions::Neon, "neon"));
|
||||
}
|
||||
for (cpu_ext, ext_name) in cpu_ext_and_name {
|
||||
for alg_name in alg_names {
|
||||
let src_image_data = U16::load_big_src_image();
|
||||
let src_view = src_image_data.view();
|
||||
let mut dst_image = Image::new(new_width, new_height, src_view.pixel_type());
|
||||
let mut dst_view = dst_image.view_mut();
|
||||
|
||||
let resize_alg = match alg_name {
|
||||
"Nearest" => ResizeAlg::Nearest,
|
||||
"Bilinear" => ResizeAlg::Convolution(FilterType::Bilinear),
|
||||
"CatmullRom" => ResizeAlg::Convolution(FilterType::CatmullRom),
|
||||
"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).unwrap();
|
||||
})
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
utils::print_md_table(bench);
|
||||
pub fn bench_downscale_l16(bench_group: &mut utils::BenchGroup) {
|
||||
type P = U16;
|
||||
let src_image = P::load_big_image().to_luma16();
|
||||
utils::image_resize(bench_group, &src_image);
|
||||
utils::resize_resize(
|
||||
bench_group,
|
||||
Gray16,
|
||||
src_image.as_raw().as_gray(),
|
||||
src_image.width(),
|
||||
src_image.height(),
|
||||
);
|
||||
utils::fir_resize::<P>(bench_group);
|
||||
}
|
||||
|
||||
bench_main!("Compare resize of U16 image", bench_downscale_l16,);
|
||||
fn main() {
|
||||
let res = utils::run_bench(bench_downscale_l16, "Compare resize of U16 image");
|
||||
utils::print_and_write_compare_result(&res);
|
||||
}
|
||||
|
||||
@@ -1,81 +1,12 @@
|
||||
use std::num::NonZeroU32;
|
||||
|
||||
use glassbench::*;
|
||||
|
||||
use fast_image_resize::pixels::U8x2;
|
||||
use fast_image_resize::{CpuExtensions, FilterType, Image, MulDiv, PixelType, ResizeAlg, Resizer};
|
||||
use testing::PixelTestingExt;
|
||||
|
||||
mod utils;
|
||||
|
||||
pub fn bench_downscale_la(bench: &mut Bench) {
|
||||
let new_width = NonZeroU32::new(852).unwrap();
|
||||
let new_height = NonZeroU32::new(567).unwrap();
|
||||
|
||||
let alg_names = ["Nearest", "Bilinear", "CatmullRom", "Lanczos3"];
|
||||
|
||||
// fast_image_resize crate;
|
||||
let mut cpu_ext_and_name = vec![(CpuExtensions::None, "rust")];
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
{
|
||||
cpu_ext_and_name.push((CpuExtensions::Sse4_1, "sse4.1"));
|
||||
cpu_ext_and_name.push((CpuExtensions::Avx2, "avx2"));
|
||||
}
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
{
|
||||
cpu_ext_and_name.push((CpuExtensions::Neon, "neon"));
|
||||
}
|
||||
for (cpu_ext, ext_name) in cpu_ext_and_name {
|
||||
for alg_name in alg_names {
|
||||
let resize_alg = match alg_name {
|
||||
"Nearest" => ResizeAlg::Nearest,
|
||||
"Bilinear" => ResizeAlg::Convolution(FilterType::Bilinear),
|
||||
"CatmullRom" => ResizeAlg::Convolution(FilterType::CatmullRom),
|
||||
"Lanczos3" => ResizeAlg::Convolution(FilterType::Lanczos3),
|
||||
_ => return,
|
||||
};
|
||||
let src_image = U8x2::load_big_src_image();
|
||||
let src_view = src_image.view();
|
||||
let mut premultiplied_src_image =
|
||||
Image::new(src_image.width(), src_image.height(), src_view.pixel_type());
|
||||
let mut dst_image = Image::new(new_width, new_height, PixelType::U8x2);
|
||||
let mut dst_view = dst_image.view_mut();
|
||||
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| match resize_alg {
|
||||
ResizeAlg::Nearest => {
|
||||
task.iter(|| {
|
||||
fast_resizer.resize(&src_view, &mut dst_view).unwrap();
|
||||
});
|
||||
}
|
||||
_ => {
|
||||
task.iter(|| {
|
||||
let mut premultiplied_view = premultiplied_src_image.view_mut();
|
||||
mul_div
|
||||
.multiply_alpha(&src_view, &mut premultiplied_view)
|
||||
.unwrap();
|
||||
fast_resizer
|
||||
.resize(&premultiplied_view.into(), &mut dst_view)
|
||||
.unwrap();
|
||||
mul_div.divide_alpha_inplace(&mut dst_view).unwrap();
|
||||
});
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
utils::print_md_table(bench);
|
||||
pub fn bench_downscale_la(bench_group: &mut utils::BenchGroup) {
|
||||
utils::fir_resize_with_alpha::<U8x2>(bench_group);
|
||||
}
|
||||
|
||||
bench_main!("Compare resize of LA image", bench_downscale_la,);
|
||||
fn main() {
|
||||
let res = utils::run_bench(bench_downscale_la, "Compare resize of LA image");
|
||||
utils::print_and_write_compare_result(&res);
|
||||
}
|
||||
|
||||
@@ -1,79 +1,12 @@
|
||||
use std::num::NonZeroU32;
|
||||
|
||||
use glassbench::*;
|
||||
|
||||
use fast_image_resize::pixels::U16x2;
|
||||
use fast_image_resize::{CpuExtensions, FilterType, Image, MulDiv, PixelType, ResizeAlg, Resizer};
|
||||
use testing::PixelTestingExt;
|
||||
|
||||
mod utils;
|
||||
|
||||
pub fn bench_downscale_la16(bench: &mut Bench) {
|
||||
let new_width = NonZeroU32::new(852).unwrap();
|
||||
let new_height = NonZeroU32::new(567).unwrap();
|
||||
|
||||
let alg_names = ["Nearest", "Bilinear", "CatmullRom", "Lanczos3"];
|
||||
|
||||
// fast_image_resize crate;
|
||||
let mut cpu_ext_and_name = vec![(CpuExtensions::None, "rust")];
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
{
|
||||
cpu_ext_and_name.push((CpuExtensions::Sse4_1, "sse4.1"));
|
||||
cpu_ext_and_name.push((CpuExtensions::Avx2, "avx2"));
|
||||
}
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
{
|
||||
cpu_ext_and_name.push((CpuExtensions::Neon, "neon"));
|
||||
}
|
||||
for (cpu_ext, ext_name) in cpu_ext_and_name {
|
||||
for alg_name in alg_names {
|
||||
let resize_alg = match alg_name {
|
||||
"Nearest" => ResizeAlg::Nearest,
|
||||
"Bilinear" => ResizeAlg::Convolution(FilterType::Bilinear),
|
||||
"CatmullRom" => ResizeAlg::Convolution(FilterType::CatmullRom),
|
||||
"Lanczos3" => ResizeAlg::Convolution(FilterType::Lanczos3),
|
||||
_ => return,
|
||||
};
|
||||
let src_image = U16x2::load_big_src_image();
|
||||
let src_view = src_image.view();
|
||||
let mut premultiplied_src_image = Image::new(
|
||||
src_image.width(),
|
||||
src_image.height(),
|
||||
src_image.pixel_type(),
|
||||
);
|
||||
let mut dst_image = Image::new(new_width, new_height, PixelType::U16x2);
|
||||
let mut dst_view = dst_image.view_mut();
|
||||
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(|| match resize_alg {
|
||||
ResizeAlg::Nearest => {
|
||||
fast_resizer.resize(&src_view, &mut dst_view).unwrap();
|
||||
}
|
||||
_ => {
|
||||
let mut premultiplied_view = premultiplied_src_image.view_mut();
|
||||
mul_div
|
||||
.multiply_alpha(&src_view, &mut premultiplied_view)
|
||||
.unwrap();
|
||||
fast_resizer
|
||||
.resize(&premultiplied_view.into(), &mut dst_view)
|
||||
.unwrap();
|
||||
mul_div.divide_alpha_inplace(&mut dst_view).unwrap();
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
utils::print_md_table(bench);
|
||||
pub fn bench_downscale_la16(bench_group: &mut utils::BenchGroup) {
|
||||
utils::fir_resize_with_alpha::<U16x2>(bench_group);
|
||||
}
|
||||
|
||||
bench_main!("Compare resize of LA16 image", bench_downscale_la16,);
|
||||
fn main() {
|
||||
let res = utils::run_bench(bench_downscale_la16, "Compare resize of LA16 image");
|
||||
utils::print_and_write_compare_result(&res);
|
||||
}
|
||||
|
||||
+17
-107
@@ -1,116 +1,26 @@
|
||||
use std::num::NonZeroU32;
|
||||
use std::thread::sleep;
|
||||
use std::time::Duration;
|
||||
|
||||
use glassbench::*;
|
||||
use image::imageops;
|
||||
use resize::Pixel::RGB8;
|
||||
use rgb::{FromSlice, RGB};
|
||||
use rgb::FromSlice;
|
||||
|
||||
use fast_image_resize::pixels::U8x3;
|
||||
use fast_image_resize::Image;
|
||||
use fast_image_resize::{CpuExtensions, FilterType, ResizeAlg, Resizer};
|
||||
use testing::PixelTestingExt;
|
||||
|
||||
mod utils;
|
||||
|
||||
pub fn bench_downscale_rgb(bench: &mut Bench) {
|
||||
let src_image = U8x3::load_big_image().to_rgb8();
|
||||
let new_width = NonZeroU32::new(852).unwrap();
|
||||
let new_height = NonZeroU32::new(567).unwrap();
|
||||
|
||||
let alg_names = ["Nearest", "Bilinear", "CatmullRom", "Lanczos3"];
|
||||
|
||||
// image crate
|
||||
// https://crates.io/crates/image
|
||||
for alg_name in alg_names {
|
||||
let filter = match alg_name {
|
||||
"Nearest" => imageops::Nearest,
|
||||
"Bilinear" => imageops::Triangle,
|
||||
"CatmullRom" => 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" => {
|
||||
// resizer doesn't support "nearest" algorithm
|
||||
task.iter(|| sleep(Duration::new(0, 1)));
|
||||
return;
|
||||
}
|
||||
"Bilinear" => resize::Type::Triangle,
|
||||
"CatmullRom" => 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;
|
||||
let mut cpu_ext_and_name = vec![(CpuExtensions::None, "rust")];
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
{
|
||||
cpu_ext_and_name.push((CpuExtensions::Sse4_1, "sse4.1"));
|
||||
cpu_ext_and_name.push((CpuExtensions::Avx2, "avx2"));
|
||||
}
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
{
|
||||
cpu_ext_and_name.push((CpuExtensions::Neon, "neon"));
|
||||
}
|
||||
for (cpu_ext, ext_name) in cpu_ext_and_name {
|
||||
for alg_name in alg_names {
|
||||
let src_image_data = U8x3::load_big_src_image();
|
||||
let src_view = src_image_data.view();
|
||||
let mut dst_image = Image::new(new_width, new_height, src_view.pixel_type());
|
||||
let mut dst_view = dst_image.view_mut();
|
||||
|
||||
let resize_alg = match alg_name {
|
||||
"Nearest" => ResizeAlg::Nearest,
|
||||
"Bilinear" => ResizeAlg::Convolution(FilterType::Bilinear),
|
||||
"CatmullRom" => ResizeAlg::Convolution(FilterType::CatmullRom),
|
||||
"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).unwrap();
|
||||
})
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
utils::print_md_table(bench);
|
||||
pub fn bench_downscale_rgb(bench_group: &mut utils::BenchGroup) {
|
||||
type P = U8x3;
|
||||
let src_image = P::load_big_image().to_rgb8();
|
||||
utils::image_resize(bench_group, &src_image);
|
||||
utils::resize_resize(
|
||||
bench_group,
|
||||
RGB8,
|
||||
src_image.as_raw().as_rgb(),
|
||||
src_image.width(),
|
||||
src_image.height(),
|
||||
);
|
||||
utils::fir_resize::<P>(bench_group);
|
||||
}
|
||||
|
||||
bench_main!("Compare resize of RGB image", bench_downscale_rgb,);
|
||||
fn main() {
|
||||
let res = utils::run_bench(bench_downscale_rgb, "Compare resize of RGB image");
|
||||
utils::print_and_write_compare_result(&res);
|
||||
}
|
||||
|
||||
+17
-108
@@ -1,117 +1,26 @@
|
||||
use std::num::NonZeroU32;
|
||||
use std::thread::sleep;
|
||||
use std::time::Duration;
|
||||
|
||||
use glassbench::*;
|
||||
use image::imageops;
|
||||
use resize::Pixel::RGB16;
|
||||
use rgb::{FromSlice, RGB};
|
||||
use rgb::FromSlice;
|
||||
|
||||
use fast_image_resize::pixels::U16x3;
|
||||
use fast_image_resize::Image;
|
||||
use fast_image_resize::{CpuExtensions, FilterType, ResizeAlg, Resizer};
|
||||
use testing::PixelTestingExt;
|
||||
|
||||
mod utils;
|
||||
|
||||
pub fn bench_downscale_rgb16(bench: &mut Bench) {
|
||||
let src_image = U16x3::load_big_image().to_rgb16();
|
||||
let new_width = NonZeroU32::new(852).unwrap();
|
||||
let new_height = NonZeroU32::new(567).unwrap();
|
||||
|
||||
let alg_names = ["Nearest", "Bilinear", "CatmullRom", "Lanczos3"];
|
||||
|
||||
// image crate
|
||||
// https://crates.io/crates/image
|
||||
for alg_name in alg_names {
|
||||
let filter = match alg_name {
|
||||
"Nearest" => imageops::Nearest,
|
||||
"Bilinear" => imageops::Triangle,
|
||||
"CatmullRom" => 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(0u16, 0u16, 0u16); (new_width.get() * new_height.get()) as usize];
|
||||
bench.task(format!("resize - {}", alg_name), |task| {
|
||||
let filter = match alg_name {
|
||||
"Nearest" => {
|
||||
// resizer doesn't support "nearest" algorithm
|
||||
task.iter(|| sleep(Duration::new(0, 1)));
|
||||
return;
|
||||
}
|
||||
"Bilinear" => resize::Type::Triangle,
|
||||
"CatmullRom" => 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,
|
||||
RGB16,
|
||||
filter,
|
||||
)
|
||||
.unwrap();
|
||||
task.iter(|| {
|
||||
resize.resize(resize_src_image, &mut dst).unwrap();
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// fast_image_resize crate;
|
||||
let src_image_data = U16x3::load_big_src_image();
|
||||
let mut cpu_ext_and_name = vec![(CpuExtensions::None, "rust")];
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
{
|
||||
cpu_ext_and_name.push((CpuExtensions::Sse4_1, "sse4.1"));
|
||||
cpu_ext_and_name.push((CpuExtensions::Avx2, "avx2"));
|
||||
}
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
{
|
||||
cpu_ext_and_name.push((CpuExtensions::Neon, "neon"));
|
||||
}
|
||||
for (cpu_ext, ext_name) in cpu_ext_and_name {
|
||||
for alg_name in alg_names {
|
||||
let src_view = src_image_data.view();
|
||||
let mut dst_image = Image::new(new_width, new_height, src_view.pixel_type());
|
||||
let mut dst_view = dst_image.view_mut();
|
||||
|
||||
let resize_alg = match alg_name {
|
||||
"Nearest" => ResizeAlg::Nearest,
|
||||
"Bilinear" => ResizeAlg::Convolution(FilterType::Bilinear),
|
||||
"CatmullRom" => ResizeAlg::Convolution(FilterType::CatmullRom),
|
||||
"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).unwrap();
|
||||
})
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
utils::print_md_table(bench);
|
||||
pub fn bench_downscale_rgb16(bench_group: &mut utils::BenchGroup) {
|
||||
type P = U16x3;
|
||||
let src_image = P::load_big_image().to_rgb16();
|
||||
utils::image_resize(bench_group, &src_image);
|
||||
utils::resize_resize(
|
||||
bench_group,
|
||||
RGB16,
|
||||
src_image.as_raw().as_rgb(),
|
||||
src_image.width(),
|
||||
src_image.height(),
|
||||
);
|
||||
utils::fir_resize::<P>(bench_group);
|
||||
}
|
||||
|
||||
bench_main!("Compare resize of RGB16 image", bench_downscale_rgb16,);
|
||||
fn main() {
|
||||
let res = utils::run_bench(bench_downscale_rgb16, "Compare resize of RGB16 image");
|
||||
utils::print_and_write_compare_result(&res);
|
||||
}
|
||||
|
||||
+15
-107
@@ -1,117 +1,25 @@
|
||||
use std::num::NonZeroU32;
|
||||
use std::thread::sleep;
|
||||
use std::time::Duration;
|
||||
|
||||
use glassbench::*;
|
||||
use resize::px::RGBA;
|
||||
use resize::Pixel::RGBA8P;
|
||||
use rgb::FromSlice;
|
||||
|
||||
use fast_image_resize::pixels::U8x4;
|
||||
use fast_image_resize::{CpuExtensions, FilterType, Image, MulDiv, ResizeAlg, Resizer};
|
||||
use testing::PixelTestingExt;
|
||||
|
||||
mod utils;
|
||||
|
||||
pub fn bench_downscale_rgba(bench: &mut Bench) {
|
||||
let src_image = U8x4::load_big_image().to_rgba8();
|
||||
let new_width = NonZeroU32::new(852).unwrap();
|
||||
let new_height = NonZeroU32::new(567).unwrap();
|
||||
|
||||
let alg_names = ["Nearest", "Bilinear", "CatmullRom", "Lanczos3"];
|
||||
|
||||
// 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" => {
|
||||
// resizer doesn't support "nearest" algorithm
|
||||
task.iter(|| sleep(Duration::new(0, 1)));
|
||||
return;
|
||||
}
|
||||
"Bilinear" => resize::Type::Triangle,
|
||||
"CatmullRom" => 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,
|
||||
RGBA8P,
|
||||
filter,
|
||||
)
|
||||
.unwrap();
|
||||
task.iter(|| {
|
||||
resize.resize(resize_src_image, &mut dst).unwrap();
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// fast_image_resize crate;
|
||||
let src_image_data = U8x4::load_big_src_image();
|
||||
let mut cpu_ext_and_name = vec![(CpuExtensions::None, "rust")];
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
{
|
||||
cpu_ext_and_name.push((CpuExtensions::Sse4_1, "sse4.1"));
|
||||
cpu_ext_and_name.push((CpuExtensions::Avx2, "avx2"));
|
||||
}
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
{
|
||||
cpu_ext_and_name.push((CpuExtensions::Neon, "neon"));
|
||||
}
|
||||
for (cpu_ext, ext_name) in cpu_ext_and_name {
|
||||
for alg_name in alg_names {
|
||||
let resize_alg = match alg_name {
|
||||
"Nearest" => ResizeAlg::Nearest,
|
||||
"Bilinear" => ResizeAlg::Convolution(FilterType::Bilinear),
|
||||
"CatmullRom" => ResizeAlg::Convolution(FilterType::CatmullRom),
|
||||
"Lanczos3" => ResizeAlg::Convolution(FilterType::Lanczos3),
|
||||
_ => return,
|
||||
};
|
||||
let src_view = src_image_data.view();
|
||||
let mut premultiplied_src_image = Image::new(
|
||||
NonZeroU32::new(src_image.width()).unwrap(),
|
||||
NonZeroU32::new(src_image.height()).unwrap(),
|
||||
src_view.pixel_type(),
|
||||
);
|
||||
let mut dst_image = Image::new(new_width, new_height, src_view.pixel_type());
|
||||
let mut dst_view = dst_image.view_mut();
|
||||
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(|| match resize_alg {
|
||||
ResizeAlg::Nearest => {
|
||||
fast_resizer.resize(&src_view, &mut dst_view).unwrap();
|
||||
}
|
||||
_ => {
|
||||
let mut premultiplied_view = premultiplied_src_image.view_mut();
|
||||
mul_div
|
||||
.multiply_alpha(&src_view, &mut premultiplied_view)
|
||||
.unwrap();
|
||||
fast_resizer
|
||||
.resize(&premultiplied_view.into(), &mut dst_view)
|
||||
.unwrap();
|
||||
mul_div.divide_alpha_inplace(&mut dst_view).unwrap();
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
utils::print_md_table(bench);
|
||||
pub fn bench_downscale_rgba(bench_group: &mut utils::BenchGroup) {
|
||||
type P = U8x4;
|
||||
let src_image = P::load_big_image().to_rgba8();
|
||||
utils::resize_resize(
|
||||
bench_group,
|
||||
RGBA8P,
|
||||
src_image.as_raw().as_rgba(),
|
||||
src_image.width(),
|
||||
src_image.height(),
|
||||
);
|
||||
utils::fir_resize_with_alpha::<P>(bench_group);
|
||||
}
|
||||
|
||||
bench_main!("Compare resize of RGBA image", bench_downscale_rgba,);
|
||||
fn main() {
|
||||
let res = utils::run_bench(bench_downscale_rgba, "Compare resize of RGBA image");
|
||||
utils::print_and_write_compare_result(&res);
|
||||
}
|
||||
|
||||
+15
-112
@@ -1,122 +1,25 @@
|
||||
use glassbench::*;
|
||||
use resize::px::RGBA;
|
||||
use resize::Pixel::RGBA16P;
|
||||
use rgb::FromSlice;
|
||||
use std::num::NonZeroU32;
|
||||
use std::thread::sleep;
|
||||
use std::time::Duration;
|
||||
|
||||
use fast_image_resize::pixels::U16x4;
|
||||
use fast_image_resize::{CpuExtensions, FilterType, Image, MulDiv, ResizeAlg, Resizer};
|
||||
use testing::PixelTestingExt;
|
||||
|
||||
mod utils;
|
||||
|
||||
pub fn bench_downscale_rgba16(bench: &mut Bench) {
|
||||
let new_width = NonZeroU32::new(852).unwrap();
|
||||
let new_height = NonZeroU32::new(567).unwrap();
|
||||
|
||||
let alg_names = ["Nearest", "Bilinear", "CatmullRom", "Lanczos3"];
|
||||
|
||||
// resize crate
|
||||
// https://crates.io/crates/resize
|
||||
let src_image = U16x4::load_big_image().to_rgba16();
|
||||
for alg_name in alg_names {
|
||||
let resize_src_image = src_image.as_raw().as_rgba();
|
||||
let mut dst =
|
||||
vec![RGBA::new(0u16, 0u16, 0u16, 0u16); (new_width.get() * new_height.get()) as usize];
|
||||
bench.task(format!("resize - {}", alg_name), |task| {
|
||||
let filter = match alg_name {
|
||||
"Nearest" => {
|
||||
// resizer doesn't support "nearest" algorithm
|
||||
task.iter(|| sleep(Duration::new(0, 1)));
|
||||
return;
|
||||
}
|
||||
"Bilinear" => resize::Type::Triangle,
|
||||
"CatmullRom" => 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,
|
||||
RGBA16P,
|
||||
filter,
|
||||
)
|
||||
.unwrap();
|
||||
task.iter(|| {
|
||||
resize.resize(resize_src_image, &mut dst).unwrap();
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// fast_image_resize crate;
|
||||
let src_image_data = U16x4::load_big_src_image();
|
||||
let mut cpu_ext_and_name = vec![(CpuExtensions::None, "rust")];
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
{
|
||||
cpu_ext_and_name.push((CpuExtensions::Sse4_1, "sse4.1"));
|
||||
cpu_ext_and_name.push((CpuExtensions::Avx2, "avx2"));
|
||||
}
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
{
|
||||
cpu_ext_and_name.push((CpuExtensions::Neon, "neon"));
|
||||
}
|
||||
for (cpu_ext, ext_name) in cpu_ext_and_name {
|
||||
for alg_name in alg_names {
|
||||
let resize_alg = match alg_name {
|
||||
"Nearest" => ResizeAlg::Nearest,
|
||||
"Bilinear" => ResizeAlg::Convolution(FilterType::Bilinear),
|
||||
"CatmullRom" => ResizeAlg::Convolution(FilterType::CatmullRom),
|
||||
"Lanczos3" => ResizeAlg::Convolution(FilterType::Lanczos3),
|
||||
_ => return,
|
||||
};
|
||||
let src_view = src_image_data.view();
|
||||
let mut premultiplied_src_image = Image::new(
|
||||
NonZeroU32::new(src_image.width()).unwrap(),
|
||||
NonZeroU32::new(src_image.height()).unwrap(),
|
||||
src_view.pixel_type(),
|
||||
);
|
||||
let mut dst_image = Image::new(new_width, new_height, src_view.pixel_type());
|
||||
let mut dst_view = dst_image.view_mut();
|
||||
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| match resize_alg {
|
||||
ResizeAlg::Nearest => {
|
||||
task.iter(|| {
|
||||
fast_resizer.resize(&src_view, &mut dst_view).unwrap();
|
||||
});
|
||||
}
|
||||
_ => {
|
||||
task.iter(|| {
|
||||
let mut premultiplied_view = premultiplied_src_image.view_mut();
|
||||
mul_div
|
||||
.multiply_alpha(&src_view, &mut premultiplied_view)
|
||||
.unwrap();
|
||||
fast_resizer
|
||||
.resize(&premultiplied_view.into(), &mut dst_view)
|
||||
.unwrap();
|
||||
mul_div.divide_alpha_inplace(&mut dst_view).unwrap();
|
||||
});
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
utils::print_md_table(bench);
|
||||
pub fn bench_downscale_rgba16(bench_group: &mut utils::BenchGroup) {
|
||||
type P = U16x4;
|
||||
let src_image = P::load_big_image().to_rgba16();
|
||||
utils::resize_resize(
|
||||
bench_group,
|
||||
RGBA16P,
|
||||
src_image.as_raw().as_rgba(),
|
||||
src_image.width(),
|
||||
src_image.height(),
|
||||
);
|
||||
utils::fir_resize_with_alpha::<P>(bench_group);
|
||||
}
|
||||
|
||||
bench_main!("Compare resize of RGBA16 image", bench_downscale_rgba16,);
|
||||
fn main() {
|
||||
let res = utils::run_bench(bench_downscale_rgba16, "Compare resize of RGBA16 image");
|
||||
utils::print_and_write_compare_result(&res);
|
||||
}
|
||||
|
||||
+54
-70
@@ -1,7 +1,5 @@
|
||||
use std::num::NonZeroU32;
|
||||
|
||||
use glassbench::*;
|
||||
|
||||
use fast_image_resize::pixels::*;
|
||||
use fast_image_resize::Image;
|
||||
use fast_image_resize::{CpuExtensions, FilterType, PixelType, ResizeAlg, Resizer};
|
||||
@@ -12,7 +10,7 @@ mod utils;
|
||||
const NEW_WIDTH: u32 = 852;
|
||||
const NEW_HEIGHT: u32 = 567;
|
||||
|
||||
fn native_nearest_u8x4_bench(bench: &mut Bench) {
|
||||
fn native_nearest_u8x4_bench(bench_group: &mut utils::BenchGroup) {
|
||||
let image = U8x4::load_big_src_image();
|
||||
let mut res_image = Image::new(
|
||||
NonZeroU32::new(NEW_WIDTH).unwrap(),
|
||||
@@ -25,15 +23,15 @@ fn native_nearest_u8x4_bench(bench: &mut Bench) {
|
||||
unsafe {
|
||||
resizer.set_cpu_extensions(CpuExtensions::None);
|
||||
}
|
||||
bench.task("nearest wo SIMD", |task| {
|
||||
task.iter(|| {
|
||||
bench_group.bench_function("nearest wo SIMD", |bencher| {
|
||||
bencher.iter(|| {
|
||||
resizer.resize(&src_image, &mut dst_image).unwrap();
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
fn downscale_bench(
|
||||
bench: &mut Bench,
|
||||
bench_group: &mut utils::BenchGroup,
|
||||
image: &Image<'static>,
|
||||
cpu_extensions: CpuExtensions,
|
||||
filter_type: FilterType,
|
||||
@@ -55,14 +53,14 @@ fn downscale_bench(
|
||||
filter_type,
|
||||
cpu_ext_into_str(cpu_extensions),
|
||||
);
|
||||
bench.task(bench_name, |task| {
|
||||
task.iter(|| {
|
||||
bench_group.bench_function(bench_name, |bencher| {
|
||||
bencher.iter(|| {
|
||||
resizer.resize(&src_image, &mut dst_image).unwrap();
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
fn native_nearest_u8_bench(bench: &mut Bench) {
|
||||
fn native_nearest_u8_bench(bench_group: &mut utils::BenchGroup) {
|
||||
let image = U8::load_big_src_image();
|
||||
let mut res_image = Image::new(
|
||||
NonZeroU32::new(NEW_WIDTH).unwrap(),
|
||||
@@ -75,71 +73,57 @@ fn native_nearest_u8_bench(bench: &mut Bench) {
|
||||
unsafe {
|
||||
resizer.set_cpu_extensions(CpuExtensions::None);
|
||||
}
|
||||
bench.task("u8 nearest wo SIMD", |task| {
|
||||
task.iter(|| {
|
||||
bench_group.bench_function("u8 nearest wo SIMD", |bencher| {
|
||||
bencher.iter(|| {
|
||||
resizer.resize(&src_image, &mut dst_image).unwrap();
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
// Pin process to #0 CPU core
|
||||
let mut cpu_set = nix::sched::CpuSet::new();
|
||||
cpu_set.set(0).unwrap();
|
||||
nix::sched::sched_setaffinity(nix::unistd::Pid::from_raw(0), &cpu_set).unwrap();
|
||||
|
||||
use glassbench::*;
|
||||
let name = env!("CARGO_CRATE_NAME");
|
||||
let cmd = Command::read();
|
||||
if cmd.include_bench(name) {
|
||||
let mut bench = create_bench(name, "Resize", &cmd);
|
||||
|
||||
let pixel_types = [
|
||||
PixelType::U8,
|
||||
PixelType::U8x2,
|
||||
PixelType::U8x3,
|
||||
PixelType::U8x4,
|
||||
PixelType::U16,
|
||||
PixelType::U16x2,
|
||||
PixelType::U16x3,
|
||||
PixelType::U16x4,
|
||||
PixelType::I32,
|
||||
];
|
||||
let mut cpu_extensions = vec![CpuExtensions::None];
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
{
|
||||
cpu_extensions.push(CpuExtensions::Sse4_1);
|
||||
cpu_extensions.push(CpuExtensions::Avx2);
|
||||
}
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
{
|
||||
cpu_extensions.push(CpuExtensions::Neon);
|
||||
}
|
||||
for pixel_type in pixel_types {
|
||||
for &cpu_extension in cpu_extensions.iter() {
|
||||
let image = match pixel_type {
|
||||
PixelType::U8 => U8::load_big_src_image(),
|
||||
PixelType::U8x2 => U8x2::load_big_src_image(),
|
||||
PixelType::U8x3 => U8x3::load_big_src_image(),
|
||||
PixelType::U8x4 => U8x4::load_big_src_image(),
|
||||
PixelType::U16 => U16::load_big_src_image(),
|
||||
PixelType::U16x2 => U16x2::load_big_src_image(),
|
||||
PixelType::U16x3 => U16x3::load_big_src_image(),
|
||||
PixelType::U16x4 => U16x4::load_big_src_image(),
|
||||
PixelType::I32 => I32::load_big_src_image(),
|
||||
_ => unreachable!(),
|
||||
};
|
||||
downscale_bench(&mut bench, &image, cpu_extension, FilterType::Lanczos3);
|
||||
}
|
||||
}
|
||||
|
||||
native_nearest_u8x4_bench(&mut bench);
|
||||
native_nearest_u8_bench(&mut bench);
|
||||
|
||||
if let Err(e) = after_bench(&mut bench, &cmd) {
|
||||
eprintln!("{:?}", e);
|
||||
}
|
||||
} else {
|
||||
println!("skipping bench {:?}", &name);
|
||||
pub fn resize_bench(bench_group: &mut utils::BenchGroup) {
|
||||
let pixel_types = [
|
||||
PixelType::U8,
|
||||
PixelType::U8x2,
|
||||
PixelType::U8x3,
|
||||
PixelType::U8x4,
|
||||
PixelType::U16,
|
||||
PixelType::U16x2,
|
||||
PixelType::U16x3,
|
||||
PixelType::U16x4,
|
||||
PixelType::I32,
|
||||
];
|
||||
let mut cpu_extensions = vec![CpuExtensions::None];
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
{
|
||||
cpu_extensions.push(CpuExtensions::Sse4_1);
|
||||
cpu_extensions.push(CpuExtensions::Avx2);
|
||||
}
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
{
|
||||
cpu_extensions.push(CpuExtensions::Neon);
|
||||
}
|
||||
for pixel_type in pixel_types {
|
||||
for &cpu_extension in cpu_extensions.iter() {
|
||||
let image = match pixel_type {
|
||||
PixelType::U8 => U8::load_big_src_image(),
|
||||
PixelType::U8x2 => U8x2::load_big_src_image(),
|
||||
PixelType::U8x3 => U8x3::load_big_src_image(),
|
||||
PixelType::U8x4 => U8x4::load_big_src_image(),
|
||||
PixelType::U16 => U16::load_big_src_image(),
|
||||
PixelType::U16x2 => U16x2::load_big_src_image(),
|
||||
PixelType::U16x3 => U16x3::load_big_src_image(),
|
||||
PixelType::U16x4 => U16x4::load_big_src_image(),
|
||||
PixelType::I32 => I32::load_big_src_image(),
|
||||
_ => unreachable!(),
|
||||
};
|
||||
downscale_bench(bench_group, &image, cpu_extension, FilterType::Lanczos3);
|
||||
}
|
||||
}
|
||||
|
||||
native_nearest_u8x4_bench(bench_group);
|
||||
native_nearest_u8_bench(bench_group);
|
||||
}
|
||||
|
||||
fn main() {
|
||||
utils::run_bench(resize_bench, "Resize");
|
||||
}
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
use std::env;
|
||||
use std::path::PathBuf;
|
||||
use std::time::SystemTime;
|
||||
|
||||
use criterion::measurement::WallTime;
|
||||
use criterion::{Bencher, BenchmarkGroup, BenchmarkId, Criterion};
|
||||
|
||||
use super::{cargo_target_directory, get_arch_name, get_results, BenchResult};
|
||||
|
||||
pub type BenchGroup<'a> = BenchmarkGroup<'a, WallTime>;
|
||||
|
||||
pub fn run_bench<F>(bench_fn: F, name: &str) -> Vec<BenchResult>
|
||||
where
|
||||
F: FnOnce(&mut BenchGroup),
|
||||
{
|
||||
pin_process_to_cpu0();
|
||||
|
||||
let arch_name = get_arch_name();
|
||||
let output_dir = criterion_output_directory().join(arch_name);
|
||||
let mut criterion = Criterion::default()
|
||||
.output_directory(&output_dir)
|
||||
.configure_from_args();
|
||||
|
||||
let now = SystemTime::now();
|
||||
|
||||
let mut group = criterion.benchmark_group(name);
|
||||
bench_fn(&mut group);
|
||||
group.finish();
|
||||
criterion.final_summary();
|
||||
|
||||
let results_dir = output_dir.join(name);
|
||||
get_results(&results_dir, &now)
|
||||
}
|
||||
|
||||
pub fn bench<S1, S2, F>(
|
||||
group: &mut BenchGroup,
|
||||
sample_size: usize,
|
||||
func_name: S1,
|
||||
parameter: S2,
|
||||
mut f: F,
|
||||
) where
|
||||
S1: Into<String>,
|
||||
S2: Into<String>,
|
||||
F: FnMut(&mut Bencher),
|
||||
{
|
||||
let parameter = parameter.into();
|
||||
group.sample_size(sample_size);
|
||||
group.bench_with_input(
|
||||
BenchmarkId::new(func_name, ¶meter),
|
||||
¶meter,
|
||||
|bencher, _| f(bencher),
|
||||
);
|
||||
}
|
||||
|
||||
/// Pin process to #0 CPU core
|
||||
pub fn pin_process_to_cpu0() {
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
{
|
||||
let mut cpu_set = nix::sched::CpuSet::new();
|
||||
cpu_set.set(0).unwrap();
|
||||
nix::sched::sched_setaffinity(nix::unistd::Pid::from_raw(0), &cpu_set).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
fn criterion_output_directory() -> PathBuf {
|
||||
if let Some(value) = env::var_os("CRITERION_HOME") {
|
||||
PathBuf::from(value)
|
||||
} else if let Some(path) = cargo_target_directory() {
|
||||
path.join("criterion")
|
||||
} else {
|
||||
PathBuf::from("target/criterion")
|
||||
}
|
||||
}
|
||||
+39
-106
@@ -1,115 +1,48 @@
|
||||
use std::collections::HashMap;
|
||||
use std::env;
|
||||
use std::path::PathBuf;
|
||||
use std::process::Command;
|
||||
|
||||
use glassbench::*;
|
||||
use serde::Deserialize;
|
||||
|
||||
pub fn print_md_table(bench: &Bench) {
|
||||
let mut res_map: HashMap<String, Vec<String>> = HashMap::new();
|
||||
let mut crate_names: Vec<String> = Vec::new();
|
||||
let mut alg_names: Vec<String> = Vec::new();
|
||||
pub use bencher::*;
|
||||
pub use resize_functions::*;
|
||||
pub use results::*;
|
||||
|
||||
for task in bench.tasks.iter() {
|
||||
if let Some(measure) = task.measure {
|
||||
let parts: Vec<&str> = task.name.split('-').map(|s| s.trim()).collect();
|
||||
let crate_name = parts[0].to_string();
|
||||
let alg_name = parts[1].to_string();
|
||||
let value = measure.total_duration.as_secs_f64() * 1000. / measure.iterations as f64;
|
||||
mod bencher;
|
||||
mod resize_functions;
|
||||
mod results;
|
||||
|
||||
if !crate_names.contains(&crate_name) {
|
||||
crate_names.push(crate_name.clone());
|
||||
}
|
||||
if !alg_names.contains(&alg_name) {
|
||||
alg_names.push(alg_name);
|
||||
}
|
||||
|
||||
if !res_map.contains_key(&crate_name) {
|
||||
res_map.insert(crate_name.clone(), Vec::new());
|
||||
}
|
||||
if let Some(values) = res_map.get_mut(&crate_name) {
|
||||
if value < 0.10 {
|
||||
values.push("-".to_string());
|
||||
} else {
|
||||
let s_value = format!("{:.2}", value);
|
||||
values.push(s_value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let first_column_width = res_map.keys().map(|s| s.len()).max().unwrap_or(0);
|
||||
let mut column_width: Vec<usize> = vec![first_column_width];
|
||||
|
||||
for (i, name) in alg_names.iter().enumerate() {
|
||||
let width = res_map.values().map(|v| v[i].len()).max().unwrap_or(0);
|
||||
column_width.push(width.max(name.len()));
|
||||
}
|
||||
|
||||
let mut first_row: Vec<String> = vec!["".to_owned()];
|
||||
alg_names.iter().for_each(|s| first_row.push(s.to_owned()));
|
||||
print_row(&column_width, &first_row);
|
||||
print_header_underline(&column_width);
|
||||
|
||||
for name in crate_names.iter() {
|
||||
if let Some(values) = res_map.get(name) {
|
||||
let mut row = vec![name.clone()];
|
||||
values.iter().for_each(|s| row.push(s.clone()));
|
||||
print_row(&column_width, &row);
|
||||
}
|
||||
}
|
||||
const fn get_arch_name() -> &'static str {
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
return "x86_64";
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
return "arm64";
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
return "wasm32";
|
||||
#[cfg(not(any(
|
||||
target_arch = "x86_64",
|
||||
target_arch = "aarch64",
|
||||
target_arch = "wasm32"
|
||||
)))]
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
fn print_row(widths: &[usize], values: &[String]) {
|
||||
for (i, (&width, value)) in widths.iter().zip(values).enumerate() {
|
||||
if i == 0 {
|
||||
print!("| {:width$} ", value, width = width);
|
||||
} else {
|
||||
print!("| {:^width$} ", value, width = width);
|
||||
}
|
||||
/// Returns the Cargo target directory, possibly calling `cargo metadata` to
|
||||
/// figure it out.
|
||||
fn cargo_target_directory() -> Option<PathBuf> {
|
||||
#[derive(Deserialize)]
|
||||
struct Metadata {
|
||||
target_directory: PathBuf,
|
||||
}
|
||||
println!("|");
|
||||
}
|
||||
|
||||
fn print_header_underline(widths: &[usize]) {
|
||||
for (i, &width) in widths.iter().enumerate() {
|
||||
if i == 0 {
|
||||
print!("|{:-<width$}", "", width = width + 2);
|
||||
} else {
|
||||
print!("|:{:-<width$}:", "", width = width);
|
||||
}
|
||||
}
|
||||
println!("|");
|
||||
}
|
||||
|
||||
/// Generates a benchmark with a consistent id
|
||||
/// (using the benchmark file title), calling
|
||||
/// the benchmarking functions given in argument.
|
||||
///
|
||||
/// ```no-test
|
||||
/// bench_main!(
|
||||
/// "Sortings",
|
||||
/// bench_number_sorting,
|
||||
/// bench_alpha_sorting,
|
||||
/// );
|
||||
/// ```
|
||||
///
|
||||
/// This generates the whole main function.
|
||||
/// If you want to set the bench name yourself
|
||||
/// (not recommanded), or change the way the launch
|
||||
/// arguments are used, you can write the main
|
||||
/// yourself and call [create_bench] and [after_bench]
|
||||
/// instead of using this macro.
|
||||
#[macro_export]
|
||||
macro_rules! bench_main {
|
||||
(
|
||||
$title: literal,
|
||||
$( $fun: path, )+
|
||||
) => {
|
||||
pub fn main() {
|
||||
// Pin process to #0 CPU core
|
||||
let mut cpu_set = nix::sched::CpuSet::new();
|
||||
cpu_set.set(0).unwrap();
|
||||
nix::sched::sched_setaffinity(nix::unistd::Pid::from_raw(0), &cpu_set).unwrap();
|
||||
glassbench!($title, $($fun,)+);
|
||||
main();
|
||||
}
|
||||
}
|
||||
env::var_os("CARGO_TARGET_DIR")
|
||||
.map(PathBuf::from)
|
||||
.or_else(|| {
|
||||
let output = Command::new(env::var_os("CARGO")?)
|
||||
.args(["metadata", "--format-version", "1"])
|
||||
.output()
|
||||
.ok()?;
|
||||
let metadata: Metadata = serde_json::from_slice(&output.stdout).ok()?;
|
||||
Some(metadata.target_directory)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -0,0 +1,212 @@
|
||||
use std::ops::Deref;
|
||||
|
||||
use image::{imageops, ImageBuffer};
|
||||
|
||||
use crate::utils::bencher::{bench, BenchGroup};
|
||||
use fast_image_resize::{CpuExtensions, FilterType, Image, MulDiv, ResizeAlg, Resizer};
|
||||
use testing::{nonzero, PixelTestingExt};
|
||||
|
||||
const ALG_NAMES: [&str; 4] = ["Nearest", "Bilinear", "CatmullRom", "Lanczos3"];
|
||||
const NEW_WIDTH: u32 = 852;
|
||||
const NEW_HEIGHT: u32 = 567;
|
||||
|
||||
/// Resize image with help of "image" crate (https://crates.io/crates/image)
|
||||
pub fn image_resize<P, C>(bench_group: &mut BenchGroup, src_image: &ImageBuffer<P, C>)
|
||||
where
|
||||
P: image::Pixel + 'static,
|
||||
C: Deref<Target = [P::Subpixel]>,
|
||||
{
|
||||
for alg_name in ALG_NAMES {
|
||||
let (filter, sample_size) = match alg_name {
|
||||
"Nearest" => (imageops::Nearest, 80),
|
||||
"Bilinear" => (imageops::Triangle, 50),
|
||||
"CatmullRom" => (imageops::CatmullRom, 30),
|
||||
"Lanczos3" => (imageops::Lanczos3, 20),
|
||||
_ => continue,
|
||||
};
|
||||
bench(bench_group, sample_size, "image", alg_name, |bencher| {
|
||||
bencher.iter(|| {
|
||||
imageops::resize(src_image, NEW_WIDTH, NEW_HEIGHT, filter);
|
||||
})
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/// Resize image with help of "resize" crate (https://crates.io/crates/resize)
|
||||
pub fn resize_resize<Format, Out>(
|
||||
bench_group: &mut BenchGroup,
|
||||
pixel_format: Format,
|
||||
src_image: &[Format::InputPixel],
|
||||
src_width: u32,
|
||||
src_height: u32,
|
||||
) where
|
||||
Out: Clone,
|
||||
Format: resize::PixelFormat<OutputPixel = Out> + Copy,
|
||||
{
|
||||
for alg_name in ALG_NAMES {
|
||||
if alg_name == "Nearest" {
|
||||
// "resize" doesn't support "nearest" algorithm
|
||||
continue;
|
||||
}
|
||||
let mut dst =
|
||||
vec![pixel_format.into_pixel(Format::new()); (NEW_WIDTH * NEW_HEIGHT) as usize];
|
||||
let sample_size = if alg_name == "Lanczos3" { 60 } else { 100 };
|
||||
|
||||
bench(bench_group, sample_size, "resize", alg_name, |bencher| {
|
||||
let filter = match alg_name {
|
||||
"Bilinear" => resize::Type::Triangle,
|
||||
"CatmullRom" => resize::Type::Catrom,
|
||||
"Lanczos3" => resize::Type::Lanczos3,
|
||||
_ => return,
|
||||
};
|
||||
let mut resizer = resize::new(
|
||||
src_width as usize,
|
||||
src_height as usize,
|
||||
NEW_WIDTH as usize,
|
||||
NEW_HEIGHT as usize,
|
||||
pixel_format,
|
||||
filter,
|
||||
)
|
||||
.unwrap();
|
||||
bencher.iter(|| {
|
||||
resizer.resize(src_image, &mut dst).unwrap();
|
||||
})
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/// Resize image with help of "fast_imager_resize" crate
|
||||
pub fn fir_resize<P: PixelTestingExt>(bench_group: &mut BenchGroup) {
|
||||
let src_image_data = P::load_big_src_image();
|
||||
let src_view = src_image_data.view();
|
||||
let mut dst_image = Image::new(
|
||||
nonzero(NEW_WIDTH),
|
||||
nonzero(NEW_HEIGHT),
|
||||
src_view.pixel_type(),
|
||||
);
|
||||
let mut dst_view = dst_image.view_mut();
|
||||
|
||||
let mut cpu_ext_and_name = vec![(CpuExtensions::None, "rust")];
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
{
|
||||
cpu_ext_and_name.push((CpuExtensions::Sse4_1, "sse4.1"));
|
||||
cpu_ext_and_name.push((CpuExtensions::Avx2, "avx2"));
|
||||
}
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
{
|
||||
cpu_ext_and_name.push((CpuExtensions::Neon, "neon"));
|
||||
}
|
||||
for (cpu_ext, ext_name) in cpu_ext_and_name {
|
||||
for alg_name in ALG_NAMES {
|
||||
let resize_alg = match alg_name {
|
||||
"Nearest" => {
|
||||
if cpu_ext != CpuExtensions::None {
|
||||
// Nearest algorithm implemented only for native Rust.
|
||||
continue;
|
||||
}
|
||||
ResizeAlg::Nearest
|
||||
}
|
||||
"Bilinear" => ResizeAlg::Convolution(FilterType::Bilinear),
|
||||
"CatmullRom" => ResizeAlg::Convolution(FilterType::CatmullRom),
|
||||
"Lanczos3" => ResizeAlg::Convolution(FilterType::Lanczos3),
|
||||
_ => continue,
|
||||
};
|
||||
let mut fast_resizer = Resizer::new(resize_alg);
|
||||
unsafe {
|
||||
fast_resizer.set_cpu_extensions(cpu_ext);
|
||||
}
|
||||
let sample_size = 100;
|
||||
|
||||
bench(
|
||||
bench_group,
|
||||
sample_size,
|
||||
format!("fir {}", ext_name),
|
||||
alg_name,
|
||||
|bencher| {
|
||||
fast_resizer.reset_internal_buffers();
|
||||
bencher.iter(|| {
|
||||
fast_resizer.resize(&src_view, &mut dst_view).unwrap();
|
||||
})
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Resize image with alpha channel with help of "fast_imager_resize" crate
|
||||
pub fn fir_resize_with_alpha<P: PixelTestingExt>(bench_group: &mut BenchGroup) {
|
||||
let src_image = P::load_big_src_image();
|
||||
let src_view = src_image.view();
|
||||
let mut premultiplied_src_image =
|
||||
Image::new(src_image.width(), src_image.height(), src_view.pixel_type());
|
||||
let mut dst_image = Image::new(
|
||||
nonzero(NEW_WIDTH),
|
||||
nonzero(NEW_HEIGHT),
|
||||
src_view.pixel_type(),
|
||||
);
|
||||
let mut dst_view = dst_image.view_mut();
|
||||
let mut mul_div = MulDiv::default();
|
||||
|
||||
let mut cpu_ext_and_name = vec![(CpuExtensions::None, "rust")];
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
{
|
||||
cpu_ext_and_name.push((CpuExtensions::Sse4_1, "sse4.1"));
|
||||
cpu_ext_and_name.push((CpuExtensions::Avx2, "avx2"));
|
||||
}
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
{
|
||||
cpu_ext_and_name.push((CpuExtensions::Neon, "neon"));
|
||||
}
|
||||
for (cpu_ext, ext_name) in cpu_ext_and_name {
|
||||
for alg_name in ALG_NAMES {
|
||||
let resize_alg = match alg_name {
|
||||
"Nearest" => {
|
||||
if cpu_ext != CpuExtensions::None {
|
||||
// Nearest algorithm implemented only for native Rust.
|
||||
continue;
|
||||
}
|
||||
ResizeAlg::Nearest
|
||||
}
|
||||
"Bilinear" => ResizeAlg::Convolution(FilterType::Bilinear),
|
||||
"CatmullRom" => ResizeAlg::Convolution(FilterType::CatmullRom),
|
||||
"Lanczos3" => ResizeAlg::Convolution(FilterType::Lanczos3),
|
||||
_ => return,
|
||||
};
|
||||
let mut fast_resizer = Resizer::new(resize_alg);
|
||||
unsafe {
|
||||
fast_resizer.set_cpu_extensions(cpu_ext);
|
||||
mul_div.set_cpu_extensions(cpu_ext);
|
||||
}
|
||||
let sample_size = 100;
|
||||
|
||||
bench(
|
||||
bench_group,
|
||||
sample_size,
|
||||
format!("fir {}", ext_name),
|
||||
alg_name,
|
||||
|bencher| {
|
||||
fast_resizer.reset_internal_buffers();
|
||||
match resize_alg {
|
||||
ResizeAlg::Nearest => {
|
||||
bencher.iter(|| {
|
||||
fast_resizer.resize(&src_view, &mut dst_view).unwrap();
|
||||
});
|
||||
}
|
||||
_ => {
|
||||
bencher.iter(|| {
|
||||
let mut premultiplied_view = premultiplied_src_image.view_mut();
|
||||
mul_div
|
||||
.multiply_alpha(&src_view, &mut premultiplied_view)
|
||||
.unwrap();
|
||||
fast_resizer
|
||||
.resize(&premultiplied_view.into(), &mut dst_view)
|
||||
.unwrap();
|
||||
mul_div.divide_alpha_inplace(&mut dst_view).unwrap();
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,267 @@
|
||||
use std::borrow::Cow;
|
||||
use std::collections::HashMap;
|
||||
use std::env;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::time::SystemTime;
|
||||
|
||||
use itertools::Itertools;
|
||||
use serde::Deserialize;
|
||||
use walkdir::WalkDir;
|
||||
|
||||
use super::get_arch_name;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct BenchResult {
|
||||
pub function_name: String,
|
||||
pub parameter: String,
|
||||
/// Estimate time in nanoseconds
|
||||
pub estimate: f64,
|
||||
}
|
||||
|
||||
impl BenchResult {
|
||||
pub fn new(function_name: String, parameter: Option<String>, path: &Path) -> Self {
|
||||
#[derive(Deserialize)]
|
||||
struct Mean {
|
||||
point_estimate: f64,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct Estimates {
|
||||
mean: Mean,
|
||||
}
|
||||
|
||||
let data =
|
||||
std::fs::read_to_string(path).expect("Unable to read file with benchmark results");
|
||||
|
||||
let estimates: Estimates =
|
||||
serde_json::from_str(&data).expect("Unable to parse JSON data with benchmark results");
|
||||
|
||||
Self {
|
||||
function_name,
|
||||
parameter: parameter.unwrap_or_default(),
|
||||
estimate: estimates.mean.point_estimate,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Find all "new/estimates.json" files inside of given directory.
|
||||
/// Get only files what were created after the given time.
|
||||
/// Read estimate time from this files and return vector of `BenchResult` instances.
|
||||
pub fn get_results(parent_dir: &PathBuf, modified_after: &SystemTime) -> Vec<BenchResult> {
|
||||
let mut result = vec![];
|
||||
if !parent_dir.is_dir() {
|
||||
println!("WARNING: Directory with bench results is absent");
|
||||
return result;
|
||||
}
|
||||
|
||||
let result_paths = WalkDir::new(parent_dir)
|
||||
.follow_links(true)
|
||||
.into_iter()
|
||||
.map(|e| e.expect("Invalid FS entry"))
|
||||
.filter(|e| e.path().ends_with("new/estimates.json"))
|
||||
.map(|e| (e.metadata().expect("Unable get metadata for FS entity"), e))
|
||||
.filter(|(m, _)| m.is_file())
|
||||
.map(|(m, e)| {
|
||||
(
|
||||
m.modified()
|
||||
.expect("Unable to get last modification time of estimates.json file"),
|
||||
e,
|
||||
)
|
||||
})
|
||||
// Exclude old results
|
||||
.filter(|(modified, _)| modified >= modified_after)
|
||||
.sorted_by_key(|(modified, _)| modified.to_owned())
|
||||
.map(|(_, e)| e.into_path());
|
||||
|
||||
for path in result_paths {
|
||||
let rel_path = path.strip_prefix(parent_dir).unwrap_or(&path).to_path_buf();
|
||||
let path_components: Vec<String> = rel_path
|
||||
.iter()
|
||||
.map(|os_str| {
|
||||
os_str
|
||||
.to_str()
|
||||
.expect("Unable to convert FS entry name into String")
|
||||
.to_string()
|
||||
})
|
||||
.collect();
|
||||
let (function_name, parameter_name) = match path_components.as_slice() {
|
||||
[f, p, _, _] => (f.to_string(), Some(p.to_string())),
|
||||
[f, _, _] => (f.to_string(), None),
|
||||
_ => panic!("Relative path to bench result is invalid"),
|
||||
};
|
||||
|
||||
result.push(BenchResult::new(function_name, parameter_name, &path));
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
|
||||
static COL_ORDER: [&str; 4] = ["Nearest", "Bilinear", "CatmullRom", "Lanczos3"];
|
||||
|
||||
pub fn build_md_table(bench_results: &[BenchResult]) -> String {
|
||||
let mut row_names: Vec<String> = Vec::new();
|
||||
let mut row_indexes: HashMap<String, usize> = HashMap::new();
|
||||
let mut col_names: Vec<String> = Vec::new();
|
||||
|
||||
for result in bench_results {
|
||||
let row_name = result.function_name.clone();
|
||||
if !row_names.contains(&row_name) {
|
||||
row_names.push(row_name.clone());
|
||||
row_indexes.insert(row_name.clone(), row_names.len() - 1);
|
||||
}
|
||||
let col_name = result.parameter.clone();
|
||||
if !col_names.contains(&col_name) {
|
||||
col_names.push(col_name.clone());
|
||||
}
|
||||
}
|
||||
|
||||
// Reorder columns
|
||||
let mut ordered_pos = 0;
|
||||
for name in COL_ORDER {
|
||||
if let Some((cur_pos, _)) = col_names.iter().find_position(|s| s.as_str() == name) {
|
||||
if cur_pos != ordered_pos {
|
||||
col_names.swap(cur_pos, ordered_pos);
|
||||
}
|
||||
ordered_pos += 1;
|
||||
}
|
||||
}
|
||||
let col_indexes: HashMap<String, usize> = col_names
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(i, v)| (v.clone(), i))
|
||||
.collect();
|
||||
|
||||
let cols_count = col_names.len();
|
||||
let mut values = vec![Cow::Borrowed("-"); row_names.len() * cols_count];
|
||||
|
||||
for result in bench_results {
|
||||
let row_index = row_indexes.get(&result.function_name).copied();
|
||||
let col_index = col_indexes.get(&result.parameter).copied();
|
||||
if let (Some(row_index), Some(col_index)) = (row_index, col_index) {
|
||||
let value = result.estimate / 1000000.;
|
||||
if value >= 0.10 {
|
||||
let value_index = row_index * cols_count + col_index;
|
||||
values[value_index] = Cow::Owned(format!("{:.2}", value));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let first_column_width = row_names.iter().map(|s| s.len()).max().unwrap_or(0);
|
||||
let mut column_width: Vec<usize> = vec![first_column_width];
|
||||
|
||||
for (col_index, col_name) in col_names.iter().enumerate() {
|
||||
let width = (0..row_names.len())
|
||||
.map(|row_index| {
|
||||
let value_index = row_index * cols_count + col_index;
|
||||
values.get(value_index).map(|v| v.len()).unwrap_or(0)
|
||||
})
|
||||
.max()
|
||||
.unwrap_or(0);
|
||||
column_width.push(width.max(col_name.len()));
|
||||
}
|
||||
|
||||
let mut first_row: Vec<String> = vec!["".to_owned()];
|
||||
col_names.iter().for_each(|s| first_row.push(s.to_owned()));
|
||||
|
||||
let mut str_buffer: Vec<String> = vec![];
|
||||
table_row(&mut str_buffer, &column_width, &first_row);
|
||||
table_header_underline(&mut str_buffer, &column_width);
|
||||
|
||||
for row_name in row_names.iter() {
|
||||
let mut row = vec![row_name.clone()];
|
||||
for col_name in col_names.iter() {
|
||||
let row_index = row_indexes.get(row_name).copied();
|
||||
let col_index = col_indexes.get(col_name).copied();
|
||||
if let (Some(row_index), Some(col_index)) = (row_index, col_index) {
|
||||
let value_index = row_index * cols_count + col_index;
|
||||
let value = values
|
||||
.get(value_index)
|
||||
.map(|v| v.to_string())
|
||||
.unwrap_or_default();
|
||||
row.push(value);
|
||||
}
|
||||
}
|
||||
table_row(&mut str_buffer, &column_width, &row);
|
||||
}
|
||||
|
||||
str_buffer.join("")
|
||||
}
|
||||
|
||||
fn table_row(buffer: &mut Vec<String>, widths: &[usize], values: &[String]) {
|
||||
for (i, (&width, value)) in widths.iter().zip(values).enumerate() {
|
||||
if i == 0 {
|
||||
buffer.push(format!("| {:width$} ", value, width = width));
|
||||
} else {
|
||||
buffer.push(format!("| {:^width$} ", value, width = width));
|
||||
}
|
||||
}
|
||||
buffer.push("|\n".to_string());
|
||||
}
|
||||
|
||||
fn table_header_underline(buffer: &mut Vec<String>, widths: &[usize]) {
|
||||
for (i, &width) in widths.iter().enumerate() {
|
||||
if i == 0 {
|
||||
buffer.push(format!("|{:-<width$}", "", width = width + 2));
|
||||
} else {
|
||||
buffer.push(format!("|:{:-<width$}:", "", width = width));
|
||||
}
|
||||
}
|
||||
buffer.push("|\n".to_string());
|
||||
}
|
||||
|
||||
fn insert_string_into_file(path: &Path, placeholder_name: &str, string: &str) {
|
||||
let mut content = std::fs::read_to_string(path).expect("Unable to read file into string");
|
||||
let start_maker = format!("[comment]: <> ({} start)\n", placeholder_name);
|
||||
let start = match content.find(&start_maker) {
|
||||
Some(s) => s,
|
||||
None => {
|
||||
println!(
|
||||
"WARNING: Can't find start marker for placeholder '{}' in file {:?}",
|
||||
placeholder_name, path
|
||||
);
|
||||
return;
|
||||
}
|
||||
};
|
||||
let end_maker = format!("[comment]: <> ({} end)", placeholder_name);
|
||||
let end = match content.find(&end_maker) {
|
||||
Some(s) => s,
|
||||
None => {
|
||||
println!(
|
||||
"WARNING: Can't find end marker for placeholder '{}' in file {:?}",
|
||||
placeholder_name, path
|
||||
);
|
||||
return;
|
||||
}
|
||||
};
|
||||
let replace_str = [start_maker.as_str(), string].join("");
|
||||
content.replace_range(start..end, &replace_str);
|
||||
std::fs::write(path, content).expect("Unable to save string into file");
|
||||
}
|
||||
|
||||
fn write_bench_results_into_file(md_table: &str) {
|
||||
let file_name = format!("benchmarks-{}.md", get_arch_name());
|
||||
let file_path = PathBuf::from(file_name);
|
||||
if !file_path.is_file() {
|
||||
panic!("Can't find file {:?} in current directory", file_path);
|
||||
}
|
||||
let crate_name = env!("CARGO_CRATE_NAME");
|
||||
insert_string_into_file(file_path.as_path(), crate_name, md_table);
|
||||
|
||||
if get_arch_name() == "x86_64" {
|
||||
let file_path = PathBuf::from("README.md");
|
||||
if !file_path.is_file() {
|
||||
panic!("Can't find file {:?} in current directory", file_path);
|
||||
}
|
||||
insert_string_into_file(file_path.as_path(), crate_name, md_table);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn print_and_write_compare_result(bench_results: &[BenchResult]) {
|
||||
if !bench_results.is_empty() {
|
||||
let md_table = build_md_table(bench_results);
|
||||
println!("{}", md_table);
|
||||
if env::var("WRITE_COMPARE_RESULT").unwrap_or_else(|_| "".to_owned()) == "1" {
|
||||
write_bench_results_into_file(&md_table);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,12 @@
|
||||
## Benchmarks of fast_image_resize crate
|
||||
## Benchmarks of fast_image_resize crate for arm64 architecture
|
||||
|
||||
Environment:
|
||||
|
||||
- CPU: Neoverse-N1 2GHz (Oracle Cloud Compute, VM.Standard.A1.Flex)
|
||||
- Ubuntu 22.04 (linux 5.15.0)
|
||||
- Rust 1.65
|
||||
- Rust 1.66.1
|
||||
- criterion = "0.4"
|
||||
- fast_image_resize = "2.4.0"
|
||||
- glassbench = "0.3.3"
|
||||
|
||||
Other Rust libraries used to compare of resizing speed:
|
||||
|
||||
@@ -29,12 +29,14 @@ Pipeline:
|
||||
- Source image [nasa-4928x3279.png](https://github.com/Cykooz/fast_image_resize/blob/main/data/nasa-4928x3279.png)
|
||||
- Numbers in table is mean duration of image resizing in milliseconds.
|
||||
|
||||
[comment]: <> (bench_compare_rgb start)
|
||||
| | Nearest | Bilinear | CatmullRom | Lanczos3 |
|
||||
|----------|:-------:|:--------:|:----------:|:--------:|
|
||||
| image | 84.33 | 170.75 | 319.95 | 448.10 |
|
||||
| resize | - | 89.86 | 179.23 | 265.31 |
|
||||
| fir rust | 0.90 | 71.68 | 87.07 | 112.47 |
|
||||
| fir neon | 0.90 | 42.73 | 57.20 | 81.35 |
|
||||
[comment]: <> (bench_compare_rgb end)
|
||||
|
||||
### Resize RGBA8 image (U8x4) 4928x3279 => 852x567
|
||||
|
||||
@@ -45,13 +47,15 @@ Pipeline:
|
||||
- Source image
|
||||
[nasa-4928x3279-rgba.png](https://github.com/Cykooz/fast_image_resize/blob/main/data/nasa-4928x3279-rgba.png)
|
||||
- Numbers in table is mean duration of image resizing in milliseconds.
|
||||
- The `image` crate does not support multiplying and dividing by alpha channel.
|
||||
- The `image` crate does not support multiplying and dividing by alpha channel.
|
||||
|
||||
[comment]: <> (bench_compare_rgba start)
|
||||
| | Nearest | Bilinear | CatmullRom | Lanczos3 |
|
||||
|----------|:-------:|:--------:|:----------:|:--------:|
|
||||
| resize | - | 99.18 | 181.80 | 276.46 |
|
||||
| fir rust | 0.97 | 92.81 | 104.67 | 153.96 |
|
||||
| fir neon | 0.97 | 44.09 | 61.19 | 82.98 |
|
||||
[comment]: <> (bench_compare_rgba end)
|
||||
|
||||
### Resize L8 image (U8) 4928x3279 => 852x567
|
||||
|
||||
@@ -63,12 +67,14 @@ Pipeline:
|
||||
has converted into grayscale image with one byte per pixel.
|
||||
- Numbers in table is mean duration of image resizing in milliseconds.
|
||||
|
||||
[comment]: <> (bench_compare_l start)
|
||||
| | Nearest | Bilinear | CatmullRom | Lanczos3 |
|
||||
|----------|:-------:|:--------:|:----------:|:--------:|
|
||||
| image | 74.86 | 105.85 | 175.70 | 243.32 |
|
||||
| resize | - | 37.14 | 83.02 | 127.44 |
|
||||
| fir rust | 0.51 | 29.42 | 37.32 | 45.47 |
|
||||
| fir neon | 0.51 | 15.00 | 19.95 | 28.16 |
|
||||
[comment]: <> (bench_compare_l end)
|
||||
|
||||
### Resize LA8 image (U8x2) 4928x3279 => 852x567
|
||||
|
||||
@@ -83,10 +89,12 @@ Pipeline:
|
||||
- The `image` crate does not support multiplying and dividing by alpha channel.
|
||||
- The `resize` crate does not support this pixel format.
|
||||
|
||||
[comment]: <> (bench_compare_la start)
|
||||
| | Nearest | Bilinear | CatmullRom | Lanczos3 |
|
||||
|----------|:-------:|:--------:|:----------:|:--------:|
|
||||
| fir rust | 0.64 | 59.82 | 74.89 | 73.10 |
|
||||
| fir neon | 0.64 | 34.80 | 39.24 | 54.70 |
|
||||
[comment]: <> (bench_compare_la end)
|
||||
|
||||
### Resize RGB16 image (U16x3) 4928x3279 => 852x567
|
||||
|
||||
@@ -98,12 +106,14 @@ Pipeline:
|
||||
has converted into RGB16 image.
|
||||
- Numbers in table is mean duration of image resizing in milliseconds.
|
||||
|
||||
[comment]: <> (bench_compare_rgb16 start)
|
||||
| | Nearest | Bilinear | CatmullRom | Lanczos3 |
|
||||
|----------|:-------:|:--------:|:----------:|:--------:|
|
||||
| image | 87.37 | 168.47 | 327.72 | 473.01 |
|
||||
| resize | - | 91.11 | 182.73 | 271.48 |
|
||||
| fir rust | 1.39 | 146.88 | 274.83 | 392.52 |
|
||||
| fir neon | 1.39 | 70.00 | 92.13 | 128.36 |
|
||||
[comment]: <> (bench_compare_rgb16 end)
|
||||
|
||||
### Resize RGBA16 image (U16x4) 4928x3279 => 852x567
|
||||
|
||||
@@ -116,11 +126,13 @@ Pipeline:
|
||||
- Numbers in table is mean duration of image resizing in milliseconds.
|
||||
- The `image` crate does not support multiplying and dividing by alpha channel.
|
||||
|
||||
[comment]: <> (bench_compare_rgba16 start)
|
||||
| | Nearest | Bilinear | CatmullRom | Lanczos3 |
|
||||
|----------|:-------:|:--------:|:----------:|:--------:|
|
||||
| resize | - | 102.42 | 185.36 | 284.94 |
|
||||
| fir rust | 1.51 | 202.31 | 365.93 | 521.22 |
|
||||
| fir neon | 1.51 | 76.89 | 117.58 | 159.40 |
|
||||
[comment]: <> (bench_compare_rgba16 end)
|
||||
|
||||
### Resize L16 image (U16) 4928x3279 => 852x567
|
||||
|
||||
@@ -132,12 +144,14 @@ Pipeline:
|
||||
has converted into grayscale image with two bytes per pixel.
|
||||
- Numbers in table is mean duration of image resizing in milliseconds.
|
||||
|
||||
[comment]: <> (bench_compare_l16 start)
|
||||
| | Nearest | Bilinear | CatmullRom | Lanczos3 |
|
||||
|----------|:-------:|:--------:|:----------:|:--------:|
|
||||
| image | 76.09 | 110.82 | 186.44 | 257.87 |
|
||||
| resize | - | 39.65 | 63.88 | 87.06 |
|
||||
| fir rust | 0.63 | 57.32 | 94.92 | 134.83 |
|
||||
| fir neon | 0.63 | 17.98 | 26.84 | 37.71 |
|
||||
[comment]: <> (bench_compare_l16 end)
|
||||
|
||||
### Resize LA16 (luma with alpha channel) image (U16x2) 4928x3279 => 852x567
|
||||
|
||||
@@ -152,7 +166,9 @@ Pipeline:
|
||||
- The `image` crate does not support multiplying and dividing by alpha channel.
|
||||
- The `resize` crate does not support this pixel format.
|
||||
|
||||
[comment]: <> (bench_compare_la16 start)
|
||||
| | Nearest | Bilinear | CatmullRom | Lanczos3 |
|
||||
|----------|:-------:|:--------:|:----------:|:--------:|
|
||||
| fir rust | 0.95 | 105.92 | 192.14 | 270.89 |
|
||||
| fir neon | 0.95 | 35.57 | 53.51 | 73.13 |
|
||||
[comment]: <> (bench_compare_la16 end)
|
||||
@@ -0,0 +1,168 @@
|
||||
## Benchmarks of fast_image_resize crate for Wasm32 architecture
|
||||
|
||||
Environment:
|
||||
|
||||
- CPU: AMD Ryzen 9 5950X
|
||||
- RAM: DDR4 3800 MHz
|
||||
- Ubuntu 22.04 (linux 5.15.0)
|
||||
- Rust 1.66.1
|
||||
- wasmtime = "4.0.0"
|
||||
- criterion = "0.4"
|
||||
- fast_image_resize = "2.4.0"
|
||||
|
||||
Other Rust libraries used to compare of resizing speed:
|
||||
|
||||
- image = "0.24.5" (<https://crates.io/crates/image>)
|
||||
- resize = "0.7.4" (<https://crates.io/crates/resize>)
|
||||
|
||||
Resize algorithms:
|
||||
|
||||
- Nearest
|
||||
- Convolution with Bilinear filter
|
||||
- Convolution with CatmullRom filter
|
||||
- Convolution with Lanczos3 filter
|
||||
|
||||
### Resize RGB8 image (U8x3) 4928x3279 => 852x567
|
||||
|
||||
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 mean duration of image resizing in milliseconds.
|
||||
|
||||
[comment]: <> (bench_compare_rgb start)
|
||||
| | Nearest | Bilinear | CatmullRom | Lanczos3 |
|
||||
|----------|:-------:|:--------:|:----------:|:--------:|
|
||||
| image | 63.39 | 243.16 | 434.54 | 652.17 |
|
||||
| resize | - | 109.40 | 202.84 | 295.71 |
|
||||
| fir rust | 0.69 | 82.65 | 141.72 | 202.39 |
|
||||
[comment]: <> (bench_compare_rgb end)
|
||||
|
||||
### Resize RGBA8 image (U8x4) 4928x3279 => 852x567
|
||||
|
||||
Pipeline:
|
||||
|
||||
`src_image => multiply by alpha => resize => divide by alpha => dst_image`
|
||||
|
||||
- Source image
|
||||
[nasa-4928x3279-rgba.png](https://github.com/Cykooz/fast_image_resize/blob/main/data/nasa-4928x3279-rgba.png)
|
||||
- Numbers in table is mean duration of image resizing in milliseconds.
|
||||
- The `image` crate does not support multiplying and dividing by alpha channel.
|
||||
|
||||
[comment]: <> (bench_compare_rgba start)
|
||||
| | Nearest | Bilinear | CatmullRom | Lanczos3 |
|
||||
|----------|:-------:|:--------:|:----------:|:--------:|
|
||||
| resize | - | 122.06 | 229.20 | 335.95 |
|
||||
| fir rust | 0.69 | 161.38 | 255.27 | 351.55 |
|
||||
[comment]: <> (bench_compare_rgba end)
|
||||
|
||||
### Resize L8 image (U8) 4928x3279 => 852x567
|
||||
|
||||
Pipeline:
|
||||
|
||||
`src_image => resize => dst_image`
|
||||
|
||||
- Source image [nasa-4928x3279.png](https://github.com/Cykooz/fast_image_resize/blob/main/data/nasa-4928x3279.png)
|
||||
has converted into grayscale image with one byte per pixel.
|
||||
- Numbers in table is mean duration of image resizing in milliseconds.
|
||||
|
||||
[comment]: <> (bench_compare_l start)
|
||||
| | Nearest | Bilinear | CatmullRom | Lanczos3 |
|
||||
|----------|:-------:|:--------:|:----------:|:--------:|
|
||||
| image | 56.44 | 198.93 | 373.78 | 530.45 |
|
||||
| resize | - | 46.04 | 77.65 | 112.78 |
|
||||
| fir rust | 0.32 | 37.53 | 60.74 | 84.91 |
|
||||
[comment]: <> (bench_compare_l end)
|
||||
|
||||
### Resize LA8 image (U8x2) 4928x3279 => 852x567
|
||||
|
||||
Pipeline:
|
||||
|
||||
`src_image => multiply by alpha => resize => divide by alpha => dst_image`
|
||||
|
||||
- Source image
|
||||
[nasa-4928x3279-rgba.png](https://github.com/Cykooz/fast_image_resize/blob/main/data/nasa-4928x3279-rgba.png)
|
||||
has converted into grayscale image with alpha channel (two bytes per pixel).
|
||||
- Numbers in table is mean duration of image resizing in milliseconds.
|
||||
- The `image` crate does not support multiplying and dividing by alpha channel.
|
||||
- The `resize` crate does not support this pixel format.
|
||||
|
||||
[comment]: <> (bench_compare_la start)
|
||||
| | Nearest | Bilinear | CatmullRom | Lanczos3 |
|
||||
|----------|:-------:|:--------:|:----------:|:--------:|
|
||||
| fir rust | 0.43 | 85.92 | 130.47 | 176.58 |
|
||||
[comment]: <> (bench_compare_la end)
|
||||
|
||||
### Resize RGB16 image (U16x3) 4928x3279 => 852x567
|
||||
|
||||
Pipeline:
|
||||
|
||||
`src_image => resize => dst_image`
|
||||
|
||||
- Source image [nasa-4928x3279.png](https://github.com/Cykooz/fast_image_resize/blob/main/data/nasa-4928x3279.png)
|
||||
has converted into RGB16 image.
|
||||
- Numbers in table is mean duration of image resizing in milliseconds.
|
||||
|
||||
[comment]: <> (bench_compare_rgb16 start)
|
||||
| | Nearest | Bilinear | CatmullRom | Lanczos3 |
|
||||
|----------|:-------:|:--------:|:----------:|:--------:|
|
||||
| image | 63.46 | 250.44 | 444.97 | 655.95 |
|
||||
| resize | - | 94.81 | 174.13 | 253.26 |
|
||||
| fir rust | 1.05 | 99.97 | 169.38 | 238.44 |
|
||||
[comment]: <> (bench_compare_rgb16 end)
|
||||
|
||||
### Resize RGBA16 image (U16x4) 4928x3279 => 852x567
|
||||
|
||||
Pipeline:
|
||||
|
||||
`src_image => multiply by alpha => resize => divide by alpha => dst_image`
|
||||
|
||||
- Source image
|
||||
[nasa-4928x3279-rgba.png](https://github.com/Cykooz/fast_image_resize/blob/main/data/nasa-4928x3279-rgba.png)
|
||||
- Numbers in table is mean duration of image resizing in milliseconds.
|
||||
- The `image` crate does not support multiplying and dividing by alpha channel.
|
||||
|
||||
[comment]: <> (bench_compare_rgba16 start)
|
||||
| | Nearest | Bilinear | CatmullRom | Lanczos3 |
|
||||
|----------|:-------:|:--------:|:----------:|:--------:|
|
||||
| resize | - | 119.79 | 222.30 | 324.49 |
|
||||
| fir rust | 1.22 | 166.55 | 247.73 | 334.47 |
|
||||
[comment]: <> (bench_compare_rgba16 end)
|
||||
|
||||
### Resize L16 image (U16) 4928x3279 => 852x567
|
||||
|
||||
Pipeline:
|
||||
|
||||
`src_image => resize => dst_image`
|
||||
|
||||
- Source image [nasa-4928x3279.png](https://github.com/Cykooz/fast_image_resize/blob/main/data/nasa-4928x3279.png)
|
||||
has converted into grayscale image with two bytes per pixel.
|
||||
- Numbers in table is mean duration of image resizing in milliseconds.
|
||||
|
||||
[comment]: <> (bench_compare_l16 start)
|
||||
| | Nearest | Bilinear | CatmullRom | Lanczos3 |
|
||||
|----------|:-------:|:--------:|:----------:|:--------:|
|
||||
| image | 55.75 | 214.72 | 412.35 | 586.57 |
|
||||
| resize | - | 46.44 | 78.74 | 113.61 |
|
||||
| fir rust | 0.42 | 44.82 | 71.45 | 99.62 |
|
||||
[comment]: <> (bench_compare_l16 end)
|
||||
|
||||
### Resize LA16 (luma with alpha channel) image (U16x2) 4928x3279 => 852x567
|
||||
|
||||
Pipeline:
|
||||
|
||||
`src_image => multiply by alpha => resize => divide by alpha => dst_image`
|
||||
|
||||
- Source image
|
||||
[nasa-4928x3279-rgba.png](https://github.com/Cykooz/fast_image_resize/blob/main/data/nasa-4928x3279-rgba.png)
|
||||
has converted into grayscale image with alpha channel (four bytes per pixel).
|
||||
- Numbers in table is mean duration of image resizing in milliseconds.
|
||||
- The `image` crate does not support multiplying and dividing by alpha channel.
|
||||
- The `resize` crate does not support this pixel format.
|
||||
|
||||
[comment]: <> (bench_compare_la16 start)
|
||||
| | Nearest | Bilinear | CatmullRom | Lanczos3 |
|
||||
|----------|:-------:|:--------:|:----------:|:--------:|
|
||||
| fir rust | 0.70 | 98.81 | 149.67 | 201.25 |
|
||||
[comment]: <> (bench_compare_la16 end)
|
||||
@@ -1,13 +1,13 @@
|
||||
## Benchmarks of fast_image_resize crate
|
||||
## Benchmarks of fast_image_resize crate for x86_64 architecture
|
||||
|
||||
Environment:
|
||||
|
||||
- CPU: AMD Ryzen 9 5950X
|
||||
- RAM: DDR4 3800 MHz
|
||||
- Ubuntu 22.04 (linux 5.15.0)
|
||||
- Rust 1.65
|
||||
- Rust 1.66.1
|
||||
- criterion = "0.4"
|
||||
- fast_image_resize = "2.4.0"
|
||||
- glassbench = "0.3.3"
|
||||
|
||||
Other Rust libraries used to compare of resizing speed:
|
||||
|
||||
@@ -30,6 +30,7 @@ Pipeline:
|
||||
- Source image [nasa-4928x3279.png](https://github.com/Cykooz/fast_image_resize/blob/main/data/nasa-4928x3279.png)
|
||||
- Numbers in table is mean duration of image resizing in milliseconds.
|
||||
|
||||
[comment]: <> (bench_compare_rgb start)
|
||||
| | Nearest | Bilinear | CatmullRom | Lanczos3 |
|
||||
|------------|:-------:|:--------:|:----------:|:--------:|
|
||||
| image | 20.66 | 82.74 | 141.56 | 199.96 |
|
||||
@@ -37,6 +38,7 @@ Pipeline:
|
||||
| fir rust | 0.28 | 39.57 | 67.00 | 98.50 |
|
||||
| fir sse4.1 | 0.28 | 9.63 | 14.13 | 19.84 |
|
||||
| fir avx2 | 0.28 | 7.73 | 9.67 | 14.66 |
|
||||
[comment]: <> (bench_compare_rgb end)
|
||||
|
||||
### Resize RGBA8 image (U8x4) 4928x3279 => 852x567
|
||||
|
||||
@@ -49,12 +51,14 @@ Pipeline:
|
||||
- Numbers in table is mean duration of image resizing in milliseconds.
|
||||
- The `image` crate does not support multiplying and dividing by alpha channel.
|
||||
|
||||
[comment]: <> (bench_compare_rgba start)
|
||||
| | Nearest | Bilinear | CatmullRom | Lanczos3 |
|
||||
|------------|:-------:|:--------:|:----------:|:--------:|
|
||||
| resize | - | 65.74 | 130.18 | 194.13 |
|
||||
| fir rust | 0.19 | 35.61 | 52.50 | 75.76 |
|
||||
| fir sse4.1 | 0.19 | 13.19 | 17.25 | 22.62 |
|
||||
| fir avx2 | 0.19 | 9.57 | 11.97 | 16.37 |
|
||||
[comment]: <> (bench_compare_rgba end)
|
||||
|
||||
### Resize L8 image (U8) 4928x3279 => 852x567
|
||||
|
||||
@@ -66,6 +70,7 @@ Pipeline:
|
||||
has converted into grayscale image with one byte per pixel.
|
||||
- Numbers in table is mean duration of image resizing in milliseconds.
|
||||
|
||||
[comment]: <> (bench_compare_l start)
|
||||
| | Nearest | Bilinear | CatmullRom | Lanczos3 |
|
||||
|------------|:-------:|:--------:|:----------:|:--------:|
|
||||
| image | 16.97 | 48.47 | 77.55 | 107.48 |
|
||||
@@ -73,6 +78,7 @@ Pipeline:
|
||||
| fir rust | 0.15 | 13.44 | 14.73 | 22.58 |
|
||||
| fir sse4.1 | 0.15 | 4.99 | 5.28 | 8.05 |
|
||||
| fir avx2 | 0.15 | 7.09 | 5.18 | 8.60 |
|
||||
[comment]: <> (bench_compare_l end)
|
||||
|
||||
### Resize LA8 image (U8x2) 4928x3279 => 852x567
|
||||
|
||||
@@ -87,11 +93,13 @@ Pipeline:
|
||||
- The `image` crate does not support multiplying and dividing by alpha channel.
|
||||
- The `resize` crate does not support this pixel format.
|
||||
|
||||
[comment]: <> (bench_compare_la start)
|
||||
| | Nearest | Bilinear | CatmullRom | Lanczos3 |
|
||||
|------------|:-------:|:--------:|:----------:|:--------:|
|
||||
| fir rust | 0.17 | 25.43 | 28.72 | 39.33 |
|
||||
| fir sse4.1 | 0.17 | 12.66 | 14.10 | 17.66 |
|
||||
| fir avx2 | 0.17 | 8.76 | 9.70 | 12.28 |
|
||||
[comment]: <> (bench_compare_la end)
|
||||
|
||||
### Resize RGB16 image (U16x3) 4928x3279 => 852x567
|
||||
|
||||
@@ -103,6 +111,7 @@ Pipeline:
|
||||
has converted into RGB16 image.
|
||||
- Numbers in table is mean duration of image resizing in milliseconds.
|
||||
|
||||
[comment]: <> (bench_compare_rgb16 start)
|
||||
| | Nearest | Bilinear | CatmullRom | Lanczos3 |
|
||||
|------------|:-------:|:--------:|:----------:|:--------:|
|
||||
| image | 20.82 | 75.42 | 127.53 | 179.75 |
|
||||
@@ -110,6 +119,7 @@ Pipeline:
|
||||
| fir rust | 0.33 | 43.32 | 78.99 | 113.80 |
|
||||
| fir sse4.1 | 0.33 | 24.42 | 39.46 | 55.70 |
|
||||
| fir avx2 | 0.33 | 20.17 | 30.73 | 36.83 |
|
||||
[comment]: <> (bench_compare_rgb16 end)
|
||||
|
||||
### Resize RGBA16 image (U16x4) 4928x3279 => 852x567
|
||||
|
||||
@@ -122,12 +132,14 @@ Pipeline:
|
||||
- Numbers in table is mean duration of image resizing in milliseconds.
|
||||
- The `image` crate does not support multiplying and dividing by alpha channel.
|
||||
|
||||
[comment]: <> (bench_compare_rgba16 start)
|
||||
| | Nearest | Bilinear | CatmullRom | Lanczos3 |
|
||||
|------------|:-------:|:--------:|:----------:|:--------:|
|
||||
| resize | - | 63.82 | 126.13 | 187.90 |
|
||||
| fir rust | 0.30 | 79.65 | 117.15 | 157.65 |
|
||||
| fir sse4.1 | 0.30 | 43.40 | 64.83 | 86.98 |
|
||||
| fir avx2 | 0.30 | 25.63 | 36.85 | 48.28 |
|
||||
[comment]: <> (bench_compare_rgba16 end)
|
||||
|
||||
### Resize L16 image (U16) 4928x3279 => 852x567
|
||||
|
||||
@@ -139,6 +151,7 @@ Pipeline:
|
||||
has converted into grayscale image with two bytes per pixel.
|
||||
- Numbers in table is mean duration of image resizing in milliseconds.
|
||||
|
||||
[comment]: <> (bench_compare_l16 start)
|
||||
| | Nearest | Bilinear | CatmullRom | Lanczos3 |
|
||||
|------------|:-------:|:--------:|:----------:|:--------:|
|
||||
| image | 17.41 | 49.38 | 78.97 | 109.71 |
|
||||
@@ -146,6 +159,7 @@ Pipeline:
|
||||
| fir rust | 0.16 | 19.20 | 27.82 | 38.54 |
|
||||
| fir sse4.1 | 0.16 | 8.07 | 13.39 | 19.30 |
|
||||
| fir avx2 | 0.16 | 6.61 | 8.60 | 13.67 |
|
||||
[comment]: <> (bench_compare_l16 end)
|
||||
|
||||
### Resize LA16 (luma with alpha channel) image (U16x2) 4928x3279 => 852x567
|
||||
|
||||
@@ -160,8 +174,10 @@ Pipeline:
|
||||
- The `image` crate does not support multiplying and dividing by alpha channel.
|
||||
- The `resize` crate does not support this pixel format.
|
||||
|
||||
[comment]: <> (bench_compare_la16 start)
|
||||
| | Nearest | Bilinear | CatmullRom | Lanczos3 |
|
||||
|------------|:-------:|:--------:|:----------:|:--------:|
|
||||
| fir rust | 0.19 | 34.47 | 52.74 | 71.32 |
|
||||
| fir sse4.1 | 0.19 | 22.10 | 34.18 | 46.62 |
|
||||
| fir avx2 | 0.19 | 15.17 | 21.85 | 29.09 |
|
||||
[comment]: <> (bench_compare_la16 end)
|
||||
@@ -0,0 +1,54 @@
|
||||
# Preparation
|
||||
|
||||
Install additional toolchains.
|
||||
- Arm64:
|
||||
```shell
|
||||
rustup target add aarch64-unknown-linux-gnu
|
||||
```
|
||||
- Wasm32:
|
||||
```shell
|
||||
rustup target add wasm32-wasi
|
||||
cargo install cargo-wasi
|
||||
```
|
||||
Install [Wasmtime](https://wasmtime.dev/).
|
||||
|
||||
# Tests
|
||||
|
||||
Run tests without saving result images as files in `./data` directory:
|
||||
```shell
|
||||
DONT_SAVE_RESULT=1 cargo test
|
||||
```
|
||||
|
||||
# Wasm32
|
||||
|
||||
Specify build target in `.cargo/config.toml` file.
|
||||
```toml
|
||||
[build]
|
||||
target = "wasm32-wasi"
|
||||
```
|
||||
|
||||
Template of command to run `cargo` commands with using `Wasmtime`:
|
||||
```
|
||||
CARGO_TARGET_WASM32_WASI_RUNNER="wasmtime --dir=." cargo wasi <any cargo command>
|
||||
```
|
||||
|
||||
Run tests:
|
||||
```shell
|
||||
CARGO_TARGET_WASM32_WASI_RUNNER="wasmtime --dir=." cargo wasi test
|
||||
```
|
||||
|
||||
Run tests without saving result images as files in `./data` directory:
|
||||
```shell
|
||||
CARGO_TARGET_WASM32_WASI_RUNNER="wasmtime --dir=. --env DONT_SAVE_RESULT=1" cargo wasi test
|
||||
```
|
||||
|
||||
Run a specific benchmark in `quick` mode:
|
||||
```shell
|
||||
CARGO_TARGET_WASM32_WASI_RUNNER="wasmtime --dir=." cargo wasi bench --bench bench_resize -- --quick
|
||||
```
|
||||
|
||||
Run benchmarks to compare with other image resize crates and write results into
|
||||
report files, such as `./benchmarks-x86_64.md`:
|
||||
```shell
|
||||
CARGO_TARGET_WASM32_WASI_RUNNER="wasmtime --dir=. --env WRITE_COMPARE_RESULT=1" cargo wasi bench -- Compare
|
||||
```
|
||||
Reference in New Issue
Block a user