Fastest pure Rust implementation of LZ4 compression/decompression.
lz4_flex

Rust 中最快的 LZ4 实现。最初基于 redox-os 的 lz4 压缩,但现在已完全重写。 表格中的结果来自本项目的基准测试(66Kb JSON、10MB dickens),采用块格式。
AMD Ryzen 7 5900HX,rustc 1.69.0 (84c898d65 2023-04-16),Manjaro,CPU 睿频已禁用,CPU 调控器:性能模式
66Kb JSON
| 压缩器 | 压缩速度 | 解压速度 | 压缩比 |
|---|---|---|---|
| lz4_flex unsafe w. unchecked_decode | 1615 MiB/s | 5973 MiB/s | 0.2284 |
| lz4_flex unsafe | 1615 MiB/s | 5512 MiB/s | 0.2284 |
| lz4_flex safe | 1272 MiB/s | 4540 MiB/s | 0.2284 |
| lzzz (lz4 1.9.3) | 1469 MiB/s | 5313 MiB/s | 0.2283 |
| lz4_fear | 662 MiB/s | 939 MiB/s | 0.2283 |
| snap | 1452 MiB/s | 1649 MiB/s | 0.2242 |
10 Mb dickens
| 压缩器 | 压缩速度 | 解压速度 | 压缩比 |
|---|---|---|---|
| lz4_flex unsafe w. unchecked_decode | 347 MiB/s | 3168 MiB/s | 0.6372 |
| lz4_flex unsafe | 347 MiB/s | 2734 MiB/s | 0.6372 |
| lz4_flex safe | 259 MiB/s | 2338 MiB/s | 0.6372 |
| lzzz (lz4 1.9.3) | 324 MiB/s | 2759 MiB/s | 0.6372 |
| lz4_fear | 201 MiB/s | 370 MiB/s | 0.6372 |
| snap | 286 MiB/s | 679 MiB/s | 0.6276 |
特性
- 非常棒的徽标
- LZ4 块格式
- LZ4 帧格式(感谢 @arthurprs)
- 高性能
- 1.5 秒干净发布构建时间
- 用于配置安全/不安全代码使用的特性标志
- 块格式支持 no-std(感谢 @coolreader18)
- 32 位支持
使用方法:
在默认启用 “safe-encode” 和 “safe-decode” 特性标志的情况下,压缩和解压缩过程不涉及不安全代码。如果需要更高性能,您可以禁用这些特性(例如,使用 no-default-features)。
安全模式:
lz4_flex = { version = "0.12" }
性能:
lz4_flex = { version = "0.12", default-features = false, features = ["alloc"] }
块格式
块格式仅适用于较小的数据块,因为块的压缩/解压缩是在内存中进行的。 对于较大的数据,请使用帧格式,帧格式由多个块组成。
use lz4_flex::block::{compress_prepend_size, decompress_size_prepended};
fn main(){
let input: &[u8] = b"Hello people, what's up?";
let compressed = compress_prepend_size(input);
let uncompressed = decompress_size_prepended(&compressed).unwrap();
assert_eq!(input, uncompressed);
}
no_std 支持
目前 no_std 仅支持块格式,因为帧格式使用 std::io::Write,而该特性在 core 中不可用。
对于没有分配器的环境,需额外禁用 alloc 特性。_into 系列变体(compress_into、decompress_into 等)操作用户提供的切片,压缩哈希表要么放置在栈上(大小根据输入数据为 8-16KB),要么由调用者通过 compress_into_with_table 提供。
基准测试
基准测试使用 criterion 运行,测试文件位于 benches 文件夹中。
目前对比了 4 种实现,包括本实现、lz-fear、通过 Rust 绑定的 C 版本 以及 snappy。lz4-flex 版本在启用和禁用 safe-decode 与 safe-encode 特性标志的情况下进行了测试。
- lz4_cpp: https://crates.io/crates/lzzzz
- lz-fear: https://github.com/main--/rust-lz-fear
- snap: https://github.com/burntsushi/rust-snappy
测试环境:AMD Ryzen 7 5900HX 处理器,rustc 1.69.0(84c898d65 2023-04-16),Manjaro 系统,CPU 睿频已禁用,CPU 频率 3GHz
结果 v0.11.0 02-06-2023(safe-decode 和 safe-encode 关闭)
cargo bench --no-default-features
结果 v0.11.0 02-06-2023(safe-decode 和 safe-encode 开启)
cargo bench
Miri
Miri 可用于发现与不安全代码使用相关的问题:
MIRIFLAGS="-Zmiri-disable-isolation -Zmiri-disable-stacked-borrows" cargo +nightly miri test --no-default-features --features frame
模糊测试器
此模糊测试目标为解压缩器生成损坏数据:
cargo +nightly fuzz run fuzz_decomp_corrupt_block 和 cargo +nightly fuzz run fuzz_decomp_corrupt_frame
此模糊测试目标确保解压缩器在重用输出缓冲区时不会泄露先前的数据:
cargo +nightly fuzz run fuzz_decomp_no_output_leak
此模糊测试目标确保压缩和解压缩的往返过程返回原始输入:
cargo +nightly fuzz run fuzz_roundtrip 和 cargo +nightly fuzz run fuzz_roundtrip_frame
此模糊测试目标确保使用 C++ 压缩并使用 lz4_flex 解压缩能返回原始输入:
cargo +nightly fuzz run fuzz_roundtrip_cpp_compress
其他语言的绑定
待办事项
- 高压缩率
从 v0.10 迁移到 v0.11.1
如需迁移,只需移除已使用的 checked-decode 功能标志即可。