Skip to content

svga v0.1.3

Choose a tag to compare

@WendellXY WendellXY released this 19 Sep 08:31
· 1 commit to main since this release

A second performance release. No API or behaviour changes.

Whole-file parsing (inflate + Document + Movie) drops from 549 µs to 421 µs per file, averaged over 233 real-world files on an Apple M2 Max. The pure-Rust build is now ahead of libsvga 0.2.7 linked against Apple's libz.

per file total inflate + document typed decode
svga 0.1.2 549 µs 438 µs 98 µs
svga 0.1.3 421 µs 348 µs 62 µs
libsvga + Apple libz, parse only 449 µs 329 µs 101 µs
libsvga, portable inflate 1225 µs 1095 µs 104 µs

Measured with libsvga's own svga_phase_bench and a matching Rust harness, best of 12 interleaved rounds. Allocated bytes per parse roughly halve (1.68 MB → 0.79 MB).

What changed

  • Inflate uses fdeflate, the safe-Rust inflater behind the png crate: about 20% faster than miniz_oxide on SVGA payloads, which are mostly PNG data, and within 5% of libz and libdeflate.
  • Trailing bytes are still detected exactly. fdeflate prefetches input and counts it as consumed, so its byte count alone cannot see a few stray bytes after the stream. The last 16 input bytes are fed one at a time instead: a decoder cannot finish on a byte it has not been given. Tests cover 1 to 20 trailing bytes, a doubled stream and a corrupted checksum, and the opt-in corpus test pads and truncates every real file.
  • No payload copy. Document keeps the inflated buffer as its shared storage.
  • Leaner typed decoding. Messages are walked with an iterator that decodes each value once; frames are decoded in place; the frame list is sized from the header's frame count, bounded by the sprite's own size and by Limits::max_elements, so a hostile header cannot make it allocate.

Dependencies

fdeflate is new. miniz_oxide is now used directly, for compression only. flate2 remains only to select the zip crate's pure-Rust backend, and is no longer pulled in without the zip feature.