首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >K4os.Compression.LZ4:.NET 平台的快速无损压缩库

K4os.Compression.LZ4:.NET 平台的快速无损压缩库

作者头像
郑子铭
发布2025-07-17 16:09:49
发布2025-07-17 16:09:49
33000
代码可运行
举报
运行总次数:0
代码可运行

引言

数据压缩技术常用于减少存储空间和网络传输负载。LZ4 是一种快速无损压缩算法,速度快,适合高性能场景。K4os.Compression.LZ4 是为 .NET 平台设计的 LZ4 实现,支持 .NET Core、.NET Framework、Mono、Xamarin 和 UWP。本文介绍该库的功能、用法、性能和与其他算法的对比。

LZ4 算法简介

LZ4 是一种由 Yann Collet 开发的快速无损压缩算法。压缩速度约为 400 MB/s 单核,解压速度达 2 GB/s,接近内存速度极限。相比传统压缩算法(如 zlib 和 lzma),LZ4 速度快,适合实时压缩场景,如网络传输或文件存取。

测试数据(Silesia Corpus)如下

  • zlib (7zip):压缩速度 7.5 MB/s,解压速度 110 MB/s,压缩率 44%
  • lzma (7zip):压缩速度 1.5 MB/s,解压速度 50 MB/s,压缩率 37%
  • lz4:压缩速度 280 MB/s,解压速度 520 MB/s,压缩率 57%

LZ4 速度远超传统算法,压缩率稍低,但在高吞吐量场景表现优异。

K4os.Compression.LZ4 库概述

K4os.Compression.LZ4 是一个基于 .NET Standard 2.0+ 的开源库,兼容 .NET Framework 4.6.2+ 和 .NET 5.0+。它提供三种功能包:

包名

NuGet 链接

功能描述

K4os.Compression.LZ4

NuGet

块压缩

K4os.Compression.LZ4.Streams

NuGet

流压缩

K4os.Compression.LZ4.Legacy

NuGet

兼容旧版 lz4net 格式

使用方式

K4os.Compression.LZ4 支持块压缩和流压缩,适用于不同场景。

1. 块压缩

块压缩适合处理固定大小的数据块,如网络包。

压缩级别

库支持多种压缩级别,定义在 LZ4Level 枚举中:

代码语言:javascript
代码运行次数:0
运行
复制
enum LZ4Level
{
    L00_FAST,       // 快速模式,最高压缩速度
    L03_HC, L04_HC, L05_HC, L06_HC, L07_HC, L08_HC, L09_HC, // 高压缩模式
    L10_OPT, L11_OPT, L12_MAX // 优化模式,最高压缩率
}
  • FAST:压缩速度快,适合低延迟场景。
  • HC:压缩率高,压缩速度慢。
  • OPT/MAX:压缩率最高,适合存储空间要求高的场景。

解压速度不受压缩级别影响,高压缩级别数据解压更快,因数据量小。

工具方法

LZ4Codec 类提供 MaximumOutputSize(int length) 方法,计算压缩后数据最大大小。用于分配目标缓冲区,因不可压缩数据可能比原始数据大。

压缩示例

使用 LZ4Codec.Encode 进行块压缩:

代码语言:javascript
代码运行次数:0
运行
复制
var source = new byte[1000]; // 源数据
var target = new byte[LZ4Codec.MaximumOutputSize(source.Length)]; // 目标缓冲区
var encodedLength = LZ4Codec.Encode(
    source, 0, source.Length,
    target, 0, target.Length,
    LZ4Level.L00_FAST); // 快速模式

encodedLength 表示压缩后数据长度。负值表示压缩失败,通常是目标缓冲区过小。

解压示例

解压需知道原始数据大小,压缩数据不含此信息。示例:

代码语言:javascript
代码运行次数:0
运行
复制
var source = new byte[1000]; // 压缩数据
var target = new byte[knownOutputLength]; // 需知道原始大小
var decodedLength = LZ4Codec.Decode(
    source, 0, source.Length,
    target, 0, target.Length);

需自行存储原始数据大小,或使用 LZ4PicklerLZ4Stream

LZ4Pickler

LZ4Pickler 适合快速压缩小数据块,如网络消息。自动存储原始数据长度,处理不可压缩数据。

示例:

代码语言:javascript
代码运行次数:0
运行
复制
var source = new byte[1000];
var encoded = LZ4Pickler.Pickle(source, LZ4Level.L00_FAST);
var decoded = LZ4Pickler.Unpickle(encoded);

LZ4Pickler 方便,但性能略低于手动块压缩,可能有额外内存分配。

2. 流压缩

流压缩适合处理连续数据流,如文件或网络流,通过 K4os.Compression.LZ4.Streams 包实现。依赖 K4os.Hash.xxHash,兼容 LZ4 Frame 格式。

压缩设置

LZ4EncoderSettings 类配置压缩参数:

代码语言:javascript
代码运行次数:0
运行
复制
class LZ4EncoderSettings
{
    long? ContentLength { get; set; } = null; // 未支持
    bool ChainBlocks { get; set; } = true; // 块链接
    int BlockSize { get; set; } = Mem.K64; // 块大小
    bool ContentChecksum { get; set; } = false; // 内容校验
    bool BlockChecksum { get; set; } = false; // 块校验
    uint? Dictionary => null; // 未支持
    LZ4Level CompressionLevel { get; set; } = LZ4Level.L00_FAST; // 压缩级别
    int ExtraMemory { get; set; } = 0; // 额外内存
}

默认设置够用,可调整块大小或校验选项。

压缩示例

使用 LZ4Stream.Encode 创建压缩流

代码语言:javascript
代码运行次数:0
运行
复制
using (var source = File.OpenRead("input.txt"))
using (var target = LZ4Stream.Encode(File.Create("input.txt.lz4")))
{
    source.CopyTo(target);
}
解压设置与示例

解压设置简单,通过 LZ4DecoderSettings 配置额外内存

代码语言:javascript
代码运行次数:0
运行
复制
class LZ4DecoderSettings
{
    int ExtraMemory { get; set; } = 0;
}

解压示例

代码语言:javascript
代码运行次数:0
运行
复制
using (var source = LZ4Stream.Decode(File.OpenRead("input.txt.lz4")))
using (var target = File.Create("output.txt"))
{
    source.CopyTo(target);
}

流解压兼容 LZ4 Frame 格式,忽略未实现功能(如内容校验),不影响解压。

高级流抽象

版本 1.3-beta 引入 ILZ4FrameReaderILZ4FrameWriter 接口,支持 SpanMemoryStream 等数据结构的压缩和解压。通过 LZ4Frame 类工厂方法创建。

示例(内存解压):

代码语言:javascript
代码运行次数:0
运行
复制
var decoded = LZ4Frame.Decode(encoded.AsSpan(), new ArrayBufferWriter<byte>()).WrittenMemory.ToArray();

比传统流方式快,内存分配少,适合小数据块。

3. 旧版兼容性

K4os.Compression.LZ4.Legacy 包支持旧版 lz4net 文件格式,允许读写旧格式文件。

示例(转换旧格式到新格式):

代码语言:javascript
代码运行次数:0
运行
复制
using (var source = LZ4Legacy.Decode(File.OpenRead("input.old")))
using (var target = LZ4Stream.Encode(File.Create("input.new")))
{
    source.CopyTo(target);
}

4. 内存池与性能优化

库默认启用内存池,减少分配开销。长期运行的流可能因固定内存有问题。可通过 PinnedMemory.MaxPooledSize 调整池大小,设为 0 禁用。

小数据帧(如网络包)使用 LZ4Frame 更高效。测试显示 LZ4Frame.Decode 比流方式快约 2 倍,内存分配少:

方法

数据大小

平均时间 (ns)

内存分配 (Gen0)

UseStream

128

1173.6

1.2703

UseFrameReader

128

466.2

0.0525

5. ARMv7 与 Unity 兼容性

ARMv7 架构(如 Unity 的 IL2CPP)下,库使用对齐内存访问避免崩溃。可通过 LZ4Codec.Enforce32 = true 强制 32 位模式,确保兼容性。

与其他快速压缩算法的对比

LZ4 不是唯一的快速压缩算法。其他算法包括:

  • Snappy:Google 开发,压缩速度约 250 MB/s,解压速度 500 MB/s。
  • LZO:轻量级算法,性能接近 LZ4。
  • QuickLZ:简单高效,适合嵌入式系统。
  • LZF:C# 实现,性能略低于 LZ4。

项目地址

https://github.com/MiloszKrajewski/K4os.Compression.LZ4

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2025-07-16,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 DotNet NB 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 引言
  • LZ4 算法简介
  • K4os.Compression.LZ4 库概述
  • 使用方式
    • 1. 块压缩
      • 压缩级别
      • 工具方法
      • 压缩示例
      • 解压示例
      • LZ4Pickler
    • 2. 流压缩
      • 压缩设置
      • 压缩示例
      • 解压设置与示例
      • 高级流抽象
    • 3. 旧版兼容性
    • 4. 内存池与性能优化
    • 5. ARMv7 与 Unity 兼容性
      • 与其他快速压缩算法的对比
  • 项目地址
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档