image-rs / image

Encoding and decoding images in Rust
Apache License 2.0
4.76k stars 589 forks source link

Resizing images is slow #2223

Open Shnatsel opened 2 months ago

Shnatsel commented 2 months ago

The image resizing routines in image seem to be really slow compared to the competition.

For example, fast_image_resize crate benchmarks show that image is 5x slower than libvips and fast_image_resize's fallback implementation, and 20x slower than fast_image_resize's AVX2 implementation. It also does runtime CPU feature detection.

I have run the RGB benchmarks locally against image v0.25.1 to reproduce the results, and I can confirm that they are accurate on my machine - the performance gap is real:

|            | Nearest |  Box  | Bilinear | Bicubic | Lanczos3 |
|------------|:-------:|:-----:|:--------:|:-------:|:--------:|
| image      |  21.10  |   -   |  61.47   | 103.41  |  145.23  |
| resize     |    -    | 21.92 |  43.90   |  81.38  |  120.40  |
| libvips    |  5.64   | 46.89 |  15.42   |  23.99  |  31.24   |
| fir rust   |  0.20   | 7.27  |  11.57   |  20.53  |  29.96   |
| fir sse4.1 |  0.20   | 3.23  |   4.52   |  7.91   |  11.45   |
| fir avx2   |  0.21   | 2.32  |   2.90   |  5.04   |   8.25   |
Shnatsel commented 2 months ago

It's tempting to just use fast_image_resize - or at least its fallback implementation, and perhaps make all the unsafe SIMD intrinsics an opt-in feature like we did with rav1e and its nasm feature.

The drawback is that there seems to be some unsafe code in the fallback implementation that would need to be audited. Also, it seems the crate has never been fuzzed.