从零实现 DEFLATE 压缩器:纯 C# 移植版如何在 Excel 场景超越 .NET 内置?

LibDeflateCompressor 性能深度分析:纯 C# DEFLATE 压缩器 vs C 原生 vs .NET 内置

引言

在 Excel 库的开发过程中,Excel Sheet XML 的压缩性能是影响写入效率的关键瓶颈。我们基于 C 版 libdeflate 实现了一个纯 C# 移植的 DEFLATE 压缩器 LibDeflateCompressor,支持多种压缩策略。本文将其与业界标杆 C 版 libdeflate 和 .NET 内置 DeflateStream 进行全面对比分析。

术语说明

为避免混淆,本文统一使用以下术语:

术语 含义 实现语言
Native C libdeflate 业界标杆,原生 C 实现的 libdeflate 库 C
C# LibDeflateCompressor 我们的纯 C# 移植版,基于 libdeflate 1.25 算法 C#
.NET DeflateStream .NET 内置压缩器,底层封装 zlib(原生 C++) API: C#, 核心: C++

测试环境

  • 测试平台:Windows x64, .NET 10
  • 测试数据
    • ExcelSheetXML:模拟真实 Excel sheet XML 结构(含行标签、单元格、共享字符串、数值等典型模式),规模 1K ~ 300K 行
    • Random:随机字节数据(1MB, 9MB)
    • Repeating:重复字符串数据(1MB, 9MB)
  • 测试方法:每种引擎多次迭代取平均值,预热后测量

三方压缩引擎

1. Native C libdeflate

  • 业界标杆,原生 C 实现
  • Level 1 专注于吞吐率优化
  • 内存分配较大(每次调用 ~138MB 分配)

2. C# LibDeflateCompressor(我们的移植版)

  • 本次实现,基于 libdeflate 1.25 算法的纯 C# 移植
  • 支持三种策略:
    • SpeedFirst:吞吐优先,仅 1 候选匹配查找,动态 Huffman 编码
    • RatioFirst:压缩比优先,4 候选匹配查找
    • Optimal(默认):混合策略,短匹配 4 候选,中匹配 2 候选
  • 低内存分配(每次调用 ~3-11MB)

3. .NET DeflateStream

  • .NET 内置实现,底层为 zlib(原生 C++)
  • Fast 模式:高吞吐率,中等压缩比
  • Optimal 模式:高压缩比,低吞吐率

核心场景:Excel Sheet XML 压缩性能

1. Fast 模式对比(吞吐优先)

Excel Sheet XML 压缩场景下的 Fast 模式对比(100K 行,21.1MB 数据):

引擎 耗时(ms) 吞吐(MB/s) 压缩比 内存分配 相对性能
Native C libdeflate L1 27.58 765.4 7.22 45.2MB 1.00x
.NET DeflateStream Fast 31.68 666.4 5.21 20.0MB 0.87x
C# LibDeflateCompressor (SpeedFirst) 52.65 401.0 5.77 3.8MB 0.52x

关键发现:

C# 移植版 SpeedFirst vs .NET DeflateStream Fast:

  • 吞吐率:C# 移植版是 .NET Fast 的 60%(401 vs 666 MB/s)
  • 压缩比:C# 移植版更高(5.77 vs 5.21)
  • 内存分配:C# 移植版仅为 .NET 的 19%(3.8 vs 20.0 MB)

C# 移植版 SpeedFirst vs Native C libdeflate:

  • 吞吐率:C# 移植版是 C 原生的 52%(401 vs 765 MB/s)
  • 压缩比:C# 移植版明显更低(5.77 vs 7.22)

2. 全规模 Excel Sheet XML 测试结果

数据规模 引擎 吞吐(MB/s) 压缩比 相对Native C
1K行 (204KB) Native C libdeflate L1 774.0 6.71 1.00x
.NET DeflateStream Fast 726.4 4.86 0.94x
C# LibDeflateCompressor (SpeedFirst) 349.0 5.46 0.45x
C# LibDeflateCompressor (Optimal/L1) 271.4 6.82 0.35x
10K行 (2.0MB) Native C libdeflate L1 919.0 7.03 1.00x
.NET DeflateStream Fast 817.1 5.07 0.89x
C# LibDeflateCompressor (SpeedFirst) 426.5 5.67 0.46x
C# LibDeflateCompressor (Optimal/L1) 304.5 7.14 0.33x
50K行 (10.5MB) Native C libdeflate L1 798.7 7.18 1.00x
.NET DeflateStream Fast 718.4 5.19 0.90x
C# LibDeflateCompressor (SpeedFirst) 441.6 5.75 0.55x
C# LibDeflateCompressor (Optimal/L1) 321.4 7.29 0.40x
100K行 (21.1MB) Native C libdeflate L1 765.4 7.22 1.00x
.NET DeflateStream Fast 666.4 5.21 0.87x
C# LibDeflateCompressor (SpeedFirst) 401.0 5.77 0.52x
C# LibDeflateCompressor (Optimal/L1) 282.8 7.31 0.37x
300K行 (64.7MB) Native C libdeflate L1 760.4 7.36 1.00x
.NET DeflateStream Fast 689.1 5.31 0.91x
C# LibDeflateCompressor (SpeedFirst) 399.6 5.89 0.53x
C# LibDeflateCompressor (Optimal/L1) 298.9 7.47 0.39x

均衡模式(Optimal)性能分析

均衡模式(CompressionLevel.Optimal)是我们的默认策略,在吞吐率和压缩比之间取得平衡。

各 Level 性能对比(100K 行 Excel Sheet XML)

Level 引擎 吞吐(MB/s) 压缩比 内存分配
Level 1 C# LibDeflateCompressor (Optimal/L1) 282.8 7.31 3.0MB
Level 2 C# LibDeflateCompressor (Optimal/L2) 225.9 7.20 5.0MB
Level 3 C# LibDeflateCompressor (Optimal/L3) 173.5 7.41 4.9MB
.NET DeflateStream (Optimal) 132.3 8.03 10.6MB
Native C libdeflate L1 765.4 7.22 45.2MB

分析:

压缩比优势

  • C# 移植版 Optimal/L1 压缩比 7.31,高于 Native C libdeflate L1 (7.22)
  • C# 移植版 Optimal/L3 压缩比 7.41,接近 .NET DeflateStream Optimal (8.03)
  • 均衡模式压缩比表现优秀

⚠️ 吞吐率差距

  • C# 移植版 Optimal/L1 吞吐率为 Native C libdeflate L1 的 37%
  • C# 移植版 Optimal/L1 吞吐率为 .NET DeflateStream Optimal 的 214%(C# 更快)

压缩比模式(SmallestSize)性能分析

压缩比模式(CompressionLevel.SmallestSize)专注于最大化压缩比。

RatioFirst 性能数据

数据规模 引擎 吞吐(MB/s) 压缩比
10K行 C# LibDeflateCompressor (RatioFirst) 291.7 7.14
.NET DeflateStream (Optimal) 170.2 7.75
Native C libdeflate L1 919.0 7.03
50K行 C# LibDeflateCompressor (RatioFirst) 294.2 7.29
.NET DeflateStream (Optimal) 128.5 7.98
Native C libdeflate L1 798.7 7.18
100K行 C# LibDeflateCompressor (RatioFirst) 264.3 7.31
.NET DeflateStream (Optimal) 132.3 8.03
Native C libdeflate L1 765.4 7.22
300K行 C# LibDeflateCompressor (RatioFirst) 262.3 7.47
.NET DeflateStream (Optimal) 121.4 8.21
Native C libdeflate L1 760.4 7.36

分析:

C# 移植版 RatioFirst vs Native C libdeflate L1

  • 压缩比更高(7.31-7.47 vs 7.03-7.36)
  • 吞吐率为 C 原生的 34%
  • 说明 C# 的 4 候选匹配查找策略有效提升了压缩比

⚠️ C# 移植版 RatioFirst vs .NET DeflateStream Optimal

  • 压缩比低于 .NET Optimal(7.3-7.5 vs 7.8-8.2)
  • 吞吐率为 .NET Optimal 的 200%+(C# 更快)

其他数据场景

Random 数据

随机数据不可压缩,所有引擎压缩比接近 1.0:

数据规模 引擎 吞吐(MB/s) 压缩比
9MB Native C libdeflate L1 135.5 1.00
C# LibDeflateCompressor (Optimal/L1) 147.5 1.00
C# LibDeflateCompressor (SpeedFirst) 133.5 1.00
.NET DeflateStream Fast 102.5 0.95

注: 小数据量下 C# 移植版甚至略快于 C 原生,因为此时不涉及复杂的匹配查找逻辑。

Repeating 数据

重复数据高压缩比场景:

数据规模 引擎 吞吐(MB/s) 压缩比
9MB Native C libdeflate L1 1789.5 320.72
C# LibDeflateCompressor (SpeedFirst) 1011.8 320.74
C# LibDeflateCompressor (Optimal/L1) 619.8 320.74
.NET DeflateStream Fast 4745.5 89.70

注: .NET DeflateStream Fast 在重复数据场景吞吐量极高,但压缩比低(RLE 优化策略不同)。


性能差距根源分析

C# 移植版 vs Native C 原生的差距(28-52%)

  1. 运行时开销

    • JIT 编译 vs AOT 编译
    • 托管代码的数组边界检查
    • 垃圾回收机制
  2. SIMD 指令生成

    • C 版可直接使用 _mm_cmpeq_epi8 等 SIMD 指令
    • C# Vector 类库需 JIT 生成等效指令,可能存在效率差异
  3. 内存访问模式

    • 指针操作 vs 托管数组访问
    • 缓存友好性
  4. 算法实现细节

    • MatchFinder 实现差异
    • Huffman 编码构建策略
    • 块分割策略

C# 移植版 vs .NET DeflateStream 的对比

  1. SpeedFirst vs .NET Fast

    • C# 移植版压缩比更高(5.77 vs 5.21)
    • 输出字节更少(节省存储)
    • 但吞吐率较低(401 vs 666 MB/s)
  2. Optimal vs .NET Optimal

    • C# 移植版吞吐率为 .NET 的 2-2.5 倍
    • 压缩比略低(7.31 vs 8.03)
    • C# 移植版更适合需要均衡表现的场景

使用建议

场景推荐

场景 推荐策略 理由
Excel Sheet XML 写入 CompressionLevel.Optimal 平衡的压缩比和吞吐率,低内存占用
高速写入场景 CompressionLevel.Fastest 最高吞吐率,压缩比可接受
存储空间有限 CompressionLevel.SmallestSize 最高压缩比,节省存储
内存受限环境 CompressionLevel.Optimal 最低内存分配

结论

优势

跨平台兼容性 :纯 C# 实现,无需原生依赖

低内存占用 :内存分配仅为 Native C 的 1/12,.NET 的 1/5

可定制策略 :支持吞吐优先、压缩比优先、均衡三种模式

高压缩比 :Optimal 模式压缩比接近 .NET Optimal,部分场景超越 Native C

独立可控:不依赖系统 zlib 版本,行为一致可预测

待改进

⚠️ 吞吐率差距 :SpeedFirst 模式为 .NET Fast 的 60%,为 Native C 的 52%

⚠️ 算法细节:部分优化策略(如动态 Huffman)仍可改进

适用场景

C# LibDeflateCompressor 特别适合

  • 需要跨平台一致行为的场景
  • 内存受限的云原生/边缘计算
  • Excel 写入等需要均衡表现的业务场景
  • 希望完全掌控压缩逻辑的定制化需求

附录:测试方法说明

数据生成

Excel Sheet XML 数据通过以下结构生成:

xml 复制代码
<worksheet>
  <sheetData>
    <row r="1">
      <c r="A1" t="sharedStr"><v>0</v></c>
      <c r="B1" t="sharedStr"><v>1</v></c>
      ...
    </row>
    ...
  </sheetData>
</worksheet>

基准测试配置

  • 预热次数:2 次
  • 测量次数:5 次
  • 取平均耗时

正确性验证

所有压缩结果均通过解压验证,确保与原始数据一致。


文档生成时间:2026-07-27

测试平台:Windows x64, .NET 10