Zlib内存使用/性能。使用500kb的数据。

5

zLib是否值得使用?还有其他更适合的压缩器吗?

我正在使用嵌入式系统。经常情况下,我的应用程序只有3MB或更少的可用RAM。因此,我考虑使用zlib来压缩我的缓冲区。但我担心它会带来额外的开销。

缓冲区的平均大小将为30kb。这可能不会被zlib压缩。有没有人知道适用于极限内存环境的好的压缩器?

然而,我偶尔会遇到最大的缓冲区大小为700kb,其中500kb更为常见。在这种情况下,zlib值得使用吗?还是开销太大不能证明其效益?

我的唯一考虑因素是算法的RAM开销至少与zlib同样好的性能

LICENSE:我希望压缩器在BSD、zLib或等效许可下获得许可。


当您说“性能”时,是指速度还是压缩比?在嵌入式系统中,您将进行压缩、解压缩还是两者都有?您更关心压缩性能还是解压缩性能? - Craig McQueen
1
两者都可以。而“性能”指的是RAM使用/开销。 - unixman83
3个回答

5
如果您使用lm_init()初始化zlib,并选择123,则将使用deflate_fast()程序而不是deflate(),这将使用更小的运行时缓冲区和更快的算法。这样做的代价是压缩效果较差。但这可能是值得的。
如果您使用SMALL_MEM进行编译,则在对输入字符串进行哈希处理时会使用较小的哈希桶。文档(在deflate.c中)称:
/* Compile with MEDIUM_MEM to reduce the memory requirements or
 * with SMALL_MEM to use as little memory as possible. Use BIG_MEM if the
 * entire input file can be held in memory (not possible on 16 bit systems).
 * Warning: defining these symbols affects HASH_BITS (see below) and thus
 * affects the compression ratio. The compressed output
 * is still correct, and might even be smaller in some cases.
 */

希望这两种技术的结合可以使zlib与您的应用程序相匹配。它是一个无处不在的标准,能够重复使用经过磨损的组件可能值得在应用程序的其他方面做出牺牲。但是,如果您了解数据分布情况,可以编写自己的压缩例程,也许可以做得更好,但是您可以快速地放置zlib-编写和测试自己的例程可能需要更多时间。

更新

这里是使用不同的压缩级别设置在一个使用SMALL_MEM构建的zlib上的输出结果,在我找到的第一个600k文件上:

$ ls -l abi-2.6.31-14-generic
-rw-r--r-- 1 sarnold sarnold 623709 2011-03-18 18:09 abi-2.6.31-14-generic
$ for i in `seq 1 9` ; do /usr/bin/time ./gzip -c -${i} abi-2.6.31-14-generic | wc -c ; done
0.02user 0.00system 0:00.02elapsed 76%CPU (0avgtext+0avgdata 2816maxresident)k
0inputs+0outputs (0major+213minor)pagefaults 0swaps
162214
0.01user 0.00system 0:00.01elapsed 52%CPU (0avgtext+0avgdata 2800maxresident)k
0inputs+0outputs (0major+212minor)pagefaults 0swaps
158817
0.02user 0.00system 0:00.02elapsed 95%CPU (0avgtext+0avgdata 2800maxresident)k
0inputs+0outputs (0major+212minor)pagefaults 0swaps
156708
0.02user 0.00system 0:00.02elapsed 76%CPU (0avgtext+0avgdata 2784maxresident)k
0inputs+0outputs (0major+211minor)pagefaults 0swaps
143843
0.03user 0.00system 0:00.03elapsed 96%CPU (0avgtext+0avgdata 2784maxresident)k
0inputs+0outputs (0major+212minor)pagefaults 0swaps
140706
0.03user 0.00system 0:00.03elapsed 81%CPU (0avgtext+0avgdata 2784maxresident)k
0inputs+0outputs (0major+211minor)pagefaults 0swaps
140126
0.04user 0.00system 0:00.04elapsed 95%CPU (0avgtext+0avgdata 2784maxresident)k
0inputs+0outputs (0major+211minor)pagefaults 0swaps
138801
0.05user 0.00system 0:00.05elapsed 84%CPU (0avgtext+0avgdata 2784maxresident)k
0inputs+0outputs (0major+212minor)pagefaults 0swaps
138446
0.06user 0.00system 0:00.06elapsed 96%CPU (0avgtext+0avgdata 2768maxresident)k
0inputs+0outputs (0major+210minor)pagefaults 0swaps
138446

整个gzip程序需要大约2.6兆字节的内存,无论要求什么压缩级别;也许只使用您需要的特定函数而不是整个gzip程序可以将该数字降低一些,但这可能对您的小型机器来说太昂贵了。

1
SMALL_MEM已经过时。在Debian中出现了模糊的引用,似乎表明它在现代库中已经不再需要。在最近的源代码压缩包中也没有找到它。 - unixman83
Unixman83,hrm;我从Ubuntu的apt-get source gzip获取了我的源代码。我想知道他们跟Debian的源代码相差多少。 - sarnold
1
也许这是一个Debian特定的补丁。SMALL_MEM在zlib.net的生产版本中并没有显示出来。 - unixman83

4
请看LZO
根据文档:
  • 解压缩无需内存。
  • 压缩需要64 kB内存。
如果您巧妙地安排数据,您可以进行重叠(就地)解压缩,这意味着您可以将解压缩到与压缩数据相同的块中。在进行压缩时,您还可以部分重叠缓冲区。

许可证几乎使我无法将其标记为答案。我更喜欢 zLib 或 BSD 许可证。 - unixman83
1
Unixman83,顺便提一下,许可证可能只是一个小烦恼:你可能可以拼凑出一个新的守护进程过程,通过管道提供的数据进行解压缩,以使你的代码免受GPL的“链接病毒”的影响。如果LZO确实在比zlib更少的内存中运行,并提供类似的压缩和运行时,建立内存屏障可能值得努力。 - sarnold
1
@sarnold 为了一个单独的 ELF 可执行文件,需要付出数百 KB 的代价。我使用的嵌入式设备只有 4MB 的闪存和 16MB 的 RAM 存储空间。 - unixman83
2
@unixman83,@sarnold - 此外,考虑将整个固件视为单个程序也是有争议的。但是,如果符合您的技术需求,我认为您可以轻松获得LZO的商业许可证。 - aaz

2

LZS是一种非常简单的滑动窗口压缩和解压算法,被指定用于各种互联网协议中。它可能是一个不错的技术解决方案。

我已经编写了一些C和Python代码用于LZS压缩和解压缩


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接