zrip
Pure Rust zstd codec. Levels -7 through 4 (Fast and DFast strategies). Optimized for encode throughput in transfer pipelines that need standard zstd frames at high speed.
= "0.2"
Why zrip
Fastest pure-Rust zstd encoder available. 72% faster encode than structured-zstd 0.0.40 at L3, 33% faster at L1. Faster decode than structured-zstd at L3 (40%) and L-1 (21%). 2.9x faster decode than ruzstd 0.8 at L1.
Negative levels (-7..-1) for high-throughput pipelines. Most zstd libraries only expose levels 1+.
no_std + alloc. Works in embedded and kernel contexts with the alloc
feature; frame requires std.
Dictionary compression. COVER and FastCOVER training built in for small-message workloads (log lines, JSON records, RPC payloads).
Performance
Geomean across a 15-file Silesia + misc corpus on Intel i7-8700B (x86_64,
SSE2/AVX2), performance governor, turbo off. Ratio is original / compressed;
higher is better.
zrip vs C zstd 1.5.7
Compressible (12-file geomean: Silesia text, XML, JSON, PDF, binaries)
| Level | Strategy | zrip enc | C enc | zrip dec | C dec | zrip ratio | C ratio |
|---|---|---|---|---|---|---|---|
| -7 | Fast | 385 MB/s | 485 | 981 MB/s | 1576 | 2.37x | 2.56x |
| -6 | Fast | 323 MB/s | 461 | 885 MB/s | 1528 | 2.69x | 2.68x |
| -1 | Fast | 276 MB/s | 364 | 777 MB/s | 1297 | 3.51x | 3.51x |
| 1 | Fast | 247 MB/s | 345 | 614 MB/s | 1180 | 3.87x | 4.32x |
| 3 | DFast | 190 MB/s | 233 | 788 MB/s | 1045 | 4.05x | 4.62x |
| 4 | DFast | 189 MB/s | 227 | 786 MB/s | 1009 | 4.08x | 4.65x |
Encode is 72-82% of C zstd, decode 52-75%. Ratio trails C zstd by ~10% at L1-L4. The gap is pure Rust vs hand-tuned C with SIMD assembly.
Incompressible (3-file geomean: SAO star catalog, X-ray, MRI)
| Level | Strategy | zrip enc | C enc | zrip dec | C dec | zrip ratio | C ratio |
|---|---|---|---|---|---|---|---|
| -7 | Fast | 1074 MB/s | 990 | 2948 MB/s | 3996 | 1.26x | 1.30x |
| -6 | Fast | 1060 MB/s | 926 | 2974 MB/s | 3669 | 1.30x | 1.30x |
| -1 | Fast | 484 MB/s | 610 | 1814 MB/s | 3216 | 1.38x | 1.38x |
| 1 | Fast | 236 MB/s | 357 | 978 MB/s | 1023 | 1.49x | 1.58x |
| 3 | DFast | 133 MB/s | 116 | 1008 MB/s | 778 | 1.54x | 1.74x |
| 4 | DFast | 123 MB/s | 108 | 917 MB/s | 724 | 1.58x | 1.80x |
Encode is 79% of C zstd at negative levels, closing to parity at L3-L4. Decode is 74-96% of C zstd. Both codecs produce near-1.0x ratios, so throughput is the only differentiator here.
API
// One-shot (allocating)
let compressed = compress?;
let original = decompress?;
// One-shot into caller buffer
let n = compress_into?;
decompress_into?;
// Reusable context (amortizes table allocation across calls)
let mut ctx = new?;
let compressed = ctx.compress?;
let mut dec = new;
let original = dec.decompress?;
Streaming
use Write;
let mut enc = new?;
enc.write_all?;
enc.write_all?;
let compressed = enc.finish?;
use Read;
let mut dec = new;
let mut out = Stringnew;
dec.read_to_string?;
Dictionary compression
let dict = from_bytes?;
let compressed = compress_with_dict?;
let original = decompress_with_dict?;
Features
| Feature | Default | Description |
|---|---|---|
std |
yes | Enables CompressContext, DecompressContext |
frame |
yes | Frame header parsing and writing; implies std |
alloc |
yes | no_std + heap via alloc crate |
dict_builder |
no | COVER/FastCOVER dictionary training |
nightly |
no | #[optimize] attributes on hot functions |
Safety
All compression and decompression logic is #![forbid(unsafe_code)]. Unsafe
is confined to two places:
unchecked.rsmodules insidebitstream/,decode/,encode/,fse/,huffman/: smallunsafe fnwrappers (get_unchecked,read_unaligned) withdebug_assert!guards, called only after block-level bounds checks.simd/: intrinsics and raw pointer arithmetic for wildcopy, copy-match, and the SIMD sequence decoder. Dispatch happens at block boundaries, not per-sequence.
Levels
| Level | Strategy | Hash table | Literals | Sequences | Notes |
|---|---|---|---|---|---|
| -7 | Fast | 32 KB | Raw | Predefined FSE | Max throughput, no entropy coding |
| -6..-1 | Fast | 32 KB | Huffman | Predefined/custom FSE | Standard encode pipeline |
| 1 | Fast | 64 KB | Huffman | Predefined/custom FSE | 7-byte min match |
| 2 | Fast | 256 KB | Huffman | Predefined/custom FSE | 6-byte min match, 1 MB window |
| 3 | DFast | 2x 128 KB | Huffman | Predefined/custom FSE | Dual hash (short + long matches) |
| 4 | DFast | 2x 256 KB | Huffman | Predefined/custom FSE | Best ratio in this crate |
Level 0 maps to the library default (currently level 1).
L-7 skips Huffman table construction and always emits raw literal blocks with predefined FSE tables. This eliminates the most expensive part of the encode pipeline (Huffman tree build, stream encoding, custom FSE table estimation) at the cost of compression ratio. The result is a valid zstd frame that any decoder handles, but with LZ4-class encode throughput.
L-6 through L2 use the full encode pipeline: Huffman-compressed literals (with treeless reuse across blocks) and predefined or custom FSE tables for sequences, whichever produces smaller output.
L3 and L4 use the DFast strategy with two hash tables (short 4-byte and long 8-byte matches) for better match quality at lower throughput.