默认开启 safe 特性,追求极限性能需设 default-features = false 并启用 alloc;Block 格式只适合较小的内存数据块,大数据应改用 Frame 格式;no_std 仅支持 Block 格式,Frame 依赖 std::io::Write
lz4_flex = { version = "0.12" }README 未说明显存或 GPU 要求,基准测试在 AMD Ryzen 7 5900HX CPU 上运行,属于纯 CPU 库
纯 Rust 实现的 LZ4 压缩库,无需 C 依赖即可获得接近 C 版本的吞吐
纯 Rust 实现的 LZ4 压缩与解压库,速度在同类纯 Rust 实现中最快,适合需要高性能压缩又不想引入 C 依赖的 Rust 项目。
核心能力
- 纯 Rust 实现 LZ4 Block 与 Frame 两种格式
- 默认 safe-encode/safe-decode 特性,不引入 unsafe
- 关闭默认特性可切换到 unsafe 路径提升速度
- 支持 no_std 与 32 位平台(仅 Block 格式)
- 提供 _into 系列接口复用调用方缓冲区
容易踩的坑
- 0.13.1最新正式版2026-05-31 · 2026-05-31 07:52 UTC
What's Changed
- Fix panic in Fromio::Error implementation for frame::Error by @phoerious in https://github.com/PSeitz/lz4_flex/pull/221
- fix: handle short compression dictionaries by @PSeitz in https://github.com/PSeitz/lz4_flex/pull/222
New Contributors
- @dglittle made their first contribution in https://github.com/PSeitz/lz4_flex/pull/205
- @phoerious made their first contribution in https://github.com/PSeitz/lz4_flex/pull/221
Full Changelog: https://github.com/PSeitz/lz4_flex/compare/0.13.0...0.13.1
- 0.13.02026-03-22 · 2026-03-22 08:19 UTC
查看更新说明
What's Changed
- add minimal security policy by @Marcono1234 in https://github.com/PSeitz/lz4_flex/pull/203
- Fix get_maximum_output_size overflow on 32-bit targets by @dglittle in https://github.com/PSeitz/lz4_flex/pull/205
- lz4_block exposes option to reuse compression dict by @matthewfollegot in https://github.com/PSeitz/lz4_flex/pull/207
New Contributors
- @Marcono1234 made their first contribution in https://github.com/PSeitz/lz4_flex/pull/203
- @dglittle made their first contribution in https://github.com/PSeitz/lz4_flex/pull/205
- @matthewfollegot made their first contribution in https://github.com/PSeitz/lz4_flex/pull/207
Full Changelog: https://github.com/PSeitz/lz4_flex/compare/0.12.0...0.13.0
- 0.12.02025-11-18 · 2025-11-18 16:30 UTC
查看更新说明
What's Changed
- Fix integer overflows when decoding large payloads by @teh-cmc in https://github.com/PSeitz/lz4_flex/pull/192
- chore(readme): add python binding impl by @LVivona in https://github.com/PSeitz/lz4_flex/pull/190
New Contributors
- @teh-cmc made their first contribution in https://github.com/PSeitz/lz4_flex/pull/192
- @LVivona made their first contribution in https://github.com/PSeitz/lz4_flex/pull/190
Full Changelog: https://github.com/PSeitz/lz4_flex/compare/0.11.5...0.12.0
- 0.112023-06-19 · 2023-06-19 03:34 UTC
查看更新说明
Documentation
- Docs: add decompress block example
Fixes
- Handle empty input in Frame Format #120
Empty input was ignored previously and didn't write anything. Now an empty Frame is written. This improves compatibility with the reference implementation and some corner cases.- Fix: Small dict leads to panic #133
compress_into_with_dict panicked when the dict passed was smaller than 4 bytes. A match has the minimum length of 4 bytes, smaller dicts will be ignored now.Features
- [breaking] invert checked-decode to unchecked-decode #134
invert `checked-decode` feature flag to `unchecked-decode` Previously setting `default-features=false` removed the bounds checks from the `checked-decode` feature flag. `unchecked-decode` inverts this, so it will needs to be deliberately deactivated. To migrate, just remove the `checked-decode` feature flag.- Allow to pass buffer larger than size #78
This removes an unnecessary check in the decompression, when the passed buffer is too big.Empty input was ignored previously and didn't write anything. Now an empty Frame is written. This improves compatibility with the reference implementation and some corner cases.- Autodetect frame blocksize #81
The default blocksize of FrameInfo is now auto instead of 64kb, it will detect the blocksize depending of the size of the first write call. This increases compression ratio and speed for use cases where the data is larger than 64kb.- Add fluent API style contruction for FrameInfo #99 (thanks @CosmicHorrorDev)
This adds in fluent API style construction for FrameInfo. Now you can do let info = FrameInfo::new() .block_size(BlockSize::Max1MB) .content_checksum(true);Performance
Replace calls to memcpy with custom function- Perf: optimize wildcopy #109
The initial check in the the 16 byte wild copy is unnecessary, since it is already done before calling the method.- Perf: faster duplicate_overlapping #114
Replace the aggressive compiler unrolling after the failed attempt #69 (wrote out of bounds in some cases) The unrolling is avoided by manually unrolling less aggressive. Decompression performance is slightly improved by ca 4%, except the smallest test case.- Perf: simplify extend_from_within_overlapping #72
extend_from_within_overlapping is used in safe decompression when overlapping data has been detected. The prev version had unnecessary assertions/safe guard, since this method is only used in safe code. Removing the temporary &mut slice also simplified assembly output. uiCA Code Analyzer Prev Tool Skylake IceLake Tiger Lake Rocket Lake uiCA Cycles 28.71 30.67 28.71 27.57 Simplified Tool Skylake IceLake TigerLake Rocket Lake uiCA Cycles 13.00 15.00 13.00 11.00- Perf: remove unnecessary assertions
those assertions are only used in safe code and therefore unnecessary- Perf: improve safe decompression performance 8-18% #73
Improve safe decompression speed by 8-18% Reduce multiple slice fetches. every slice access, also nested ones , carries some overhead. In the hot loo - 0.10lz4_flex 0.102023-01-30 · 2023-01-30 10:11 UTC
查看更新说明
What's Changed
- Add support of decoding legacy frames by @yestyle in https://github.com/PSeitz/lz4_flex/pull/66
New Contributors
- @yestyle made their first contribution in https://github.com/PSeitz/lz4_flex/pull/66
用户点评
登录用户的真实使用记录,可按版本和硬件筛选还没有人点评。第一个说出真实体验的人最有价值。
lz4_flex

Fastest LZ4 implementation in Rust. Originally based on redox-os' lz4 compression, but now a complete rewrite. The results in the table are from a benchmark in this project (66Kb JSON, 10MB dickens) with the block format.
AMD Ryzen 7 5900HX, rustc 1.69.0 (84c898d65 2023-04-16), Manjaro, CPU Boost Disabled, CPU Governor: Performance
66Kb JSON
| Compressor | Compression | Decompression | Ratio |
|---|---|---|---|
| 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
| Compressor | Compression | Decompression | Ratio |
|---|---|---|---|
| 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 |
Features
- Very good logo
- LZ4 Block format
- LZ4 Frame format (thanks @arthurprs)
- High performance
- 1,5s clean release build time
- Feature flags to configure safe/unsafe code usage
- no-std support with block format (thanks @coolreader18)
- 32-bit support
Usage:
Compression and decompression uses no unsafe via the default feature flags "safe-encode" and "safe-decode". If you need more performance you can disable them (e.g. with no-default-features).
Safe:
lz4_flex = { version = "0.12" }
Performance:
lz4_flex = { version = "0.12", default-features = false, features = ["alloc"] }
Block Format
The block format is only valid for smaller data chunks as block is de/compressed in memory. For larger data use the frame format, which consists of multiple blocks.
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 support
no_std support is currently only for the block format, since the frame format uses std::io::Write, which is not available in core.
For environments without an allocator, additionally disable the alloc feature. The _into variants
(compress_into, decompress_into, ...) operate on user-provided slices, the compression hash table is
either placed on the stack (8-16KB depending on input size) or provided by the caller via
compress_into_with_table.
Benchmarks
The benchmark is run with criterion, the test files are in the benches folder.
Currently 4 implementations are compared, this one, lz-fear, the c version via rust bindings and snappy. The lz4-flex version is tested with the feature flags safe-decode and safe-encode switched on and off.
- lz4_cpp: https://crates.io/crates/lzzzz
- lz-fear: https://github.com/main--/rust-lz-fear
- snap: https://github.com/burntsushi/rust-snappy
Tested on AMD Ryzen 7 5900HX, rustc 1.69.0 (84c898d65 2023-04-16), Manjaro, CPU Boost Disabled, CPU 3GHZ
Results v0.11.0 02-06-2023 (safe-decode and safe-encode off)
cargo bench --no-default-features
Results v0.11.0 02-06-2023 (safe-decode and safe-encode on)
cargo bench
Miri
Miri can be used to find issues related to incorrect unsafe usage:
MIRIFLAGS="-Zmiri-disable-isolation -Zmiri-disable-stacked-borrows" cargo +nightly miri test --no-default-features --features frame
Fuzzer
This fuzz target generates corrupted data for the decompressor:
cargo +nightly fuzz run fuzz_decomp_corrupt_block and cargo +nightly fuzz run fuzz_decomp_corrupt_frame
This fuzz target asserts that the decompressor does not leak previous data when reusing an output buffer:
cargo +nightly fuzz run fuzz_decomp_no_output_leak
This fuzz target asserts that a compression and decompression roundtrip returns the original input:
cargo +nightly fuzz run fuzz_roundtrip and cargo +nightly fuzz run fuzz_roundtrip_frame
This fuzz target asserts compression with cpp and decompression with lz4_flex returns the original input:
cargo +nightly fuzz run fuzz_roundtrip_cpp_compress
Bindings in other languages
TODO
- High compression
Migrate from v0.10 to v0.11.1
To migrate, just remove the checked-decode feature flag if you used it.