zlib,deflate:要分配多少内存?

fek*_*lee 13 c memory performance zlib

我正在使用zlib来压缩文本数据流.文本数据以块的形式出现,并且对于每个块,deflate()调用flush,设置为flush Z_NO_FLUSH.一旦检索到所有块,deflate()就会在flush设置为的情况下调用Z_FINISH.

当然,deflate()每次调用都不会产生压缩输出.它在内部累积数据以实现高压缩率.那没关系!每次deflate()生成压缩输出时,该输出都会附加到数据库字段 - 这是一个缓慢的过程.

但是,一旦deflate()产生压缩数据,该数据可能不适合提供的输出缓冲区,deflate_out.因此需要多次调用deflate().这就是我想要避免的:

有没有办法让它deflate_out总是足够大,以便deflate()每次它决定产生输出时,可以将所有压缩数据存储在其中?

笔记:

  • 事先知道未压缩数据的总大小.如上所述,未压缩数据以块的形式出现,压缩数据也以块的形式附加到数据库字段.

  • 在包含文件中,zconf.h我发现了以下注释.那也许是我在找什么?即(1 << (windowBits+2)) + (1 << (memLevel+9))压缩数据deflate()可能产生的最大字节数(以字节为单位)?

    /* The memory requirements for deflate are (in bytes):
                (1 << (windowBits+2)) +  (1 << (memLevel+9))
     that is: 128K for windowBits=15  +  128K for memLevel = 8  (default values)
     plus a few kilobytes for small objects. For example, if you want to reduce
     the default memory requirements from 256K to 128K, compile with
         make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
     Of course this will generally degrade compression (there's no free lunch).
    
       The memory requirements for inflate are (in bytes) 1 << windowBits
     that is, 32K for windowBits=15 (default value) plus a few kilobytes
     for small objects.
    */
    
    Run Code Online (Sandbox Code Playgroud)

Mar*_*ler 7

deflateBound()仅在单步执行所有压缩时有用,或者强制deflate压缩当前可用的所有输入数据并为所有输入发出压缩数据.你可以使用刷新参数,如Z_BLOCK,Z_PARTIAL_FLUSH等.

如果你想使用Z_NO_FLUSH,那么尝试预测下一次调用时可能发出的最大输出deflate()会变得更加困难和低效.您不知道在最后一次压缩数据突发时消耗了多少输入,因此您需要假设几乎没有任何输入,缓冲区大小不必要地增加.但是,如果您尝试估计最大输出,那么您将无缘无故地执行大量不必要的malloc或realloc,这是低效的.

没有必要避免调用deflate()来获得更多输出.如果你只是循环deflate()直到它没有更多的输出,那么你可以使用malloced一次的固定输出缓冲区.这就是deflate()和inflate()接口的设计使用方式.您可以查看http://zlib.net/zlib_how.html以获取有关如何使用该接口的详细说明示例.

顺便说一句,在最新版本的zlib(1.2.6)中有一个deflatePending()函数,可以让你知道deflate()等待传递的输出量.