png crate gets an ultrafast compression mode, up to 4x faster decompression
png is the de-facto standard Rust crate for reading and writing PNG images, used e.g. by the image crate.
Decoding speed gains
The latest release, v0.17.8, takes from 15% to 75% less time to decode images than the previous v0.17.7. 75% less time means 4x faster! The gains depend heavily on the exact image used, but even 15% is impressive given how fast the code already is.
These gains in decompression are achieved by:
- A new, specialized Zlib implementation designed specifically for PNG from the ground up. It delivers much higher performance than the generic Zlib implementation used previously.
- PNG filters were rewritten to take advantage of autovectorization, making use of SIMD without
unsafeor platform-specific code.
This should make the png crate faster than the reference C implementation in most cases. But it's difficult to benchmark libpng because its API is so unwieldy, and it doesn't provide example code for decoding an image. We'd be very happy to see such benchmark results!
Ultra-fast compression mode
Encoding images to PNG with the "fast" compression mode is now an order of magnitude faster. This is achieved using a custom Zlib compression implementation that leverages assumptions about the patterns in PNG data to get reasonable compression ratios at phenomenal speeds.
For example, when converting vector SVG images to raster PNG images with resvg, most of the time is spent compressing the PNG image. This is a lot of wasted work if we just want to read the image instead of transferring it over the network! The fast compression mode eliminates all this wasted work, resulting in huge performance and efficiency gains.
To the best of our knowledge, no other popular PNG encoder offers this functionality, in any language.
As a cherry on top, reading images encoded with fast compression mode goes through a dedicated fast path in png crate. So they're not just super-fast to encode, but also super-fast to decode if you're using the png crate!
Upgrading
Despite the dramatic changes under the hood, the API of the png crate remained the same. All you need to do to get all these improvements in your project is run cargo update!
The changes have been tested for regressions on 80,000 images, and the new Zlib implementation has been roundtrip-fuzzed to ensure correctness. The png crate as a whole also added roundtrip fuzzing. So we're quite confident in the correctness of these changes, but if you find anything amiss, please open an issue on Github.