zlib performance difference between Mac OS X系统版本和本地重新安装

zlib performance difference between Mac OS X system version and locally re-installed

我注意到系统中可用的 zlib 库与我从源代码重新安装的库之间存在重要的性能差异,尽管两者都是 zlib 版本 1.2.11。 我运行MacOS10.13.6.

这是我的基准测试代码:

#include <stdio.h>
#include <stdlib.h>

#ifdef LOCAL_ZLIB
#include "./zlib-1.2.11/zlib.h"
#else
#include <zlib.h>
#endif

int main(int argc, char *argv[])
{
    printf("zlib version  %s\n",zlibVersion());

    gzFile  testFile = gzopen(argv[1], "r");

    int buffsize = 1024*1024 ;
    char * buffer = (char *) calloc(buffsize,sizeof(char));

    while ( gzread(testFile,buffer,buffsize) >0 )
    {
        ;
    }

    free(buffer);
    gzclose(testFile);

}

它只是在缓冲区中使用 gzread 解压缩文件。

这是我对 300MB 压缩文件的测试:

使用系统版本的结果

wget ftp://ftp.sra.ebi.ac.uk/vol1/fastq/SRR374/006/SRR3744956/SRR3744956_1.fastq.gz

gcc bench_zlib.c -O3 -o bench_zlib -lz
time ./bench_zlib SRR3744956_1.fastq.gz

给出:

zlib version  1.2.11

real    0m3.711s
user    0m3.599s
sys 0m0.105s

使用本地安装 zlib 的结果

zlib 重新编译,相同版本,以静态模式链接:

wget https://www.zlib.net/zlib-1.2.11.tar.gz
tar -xzvf zlib-1.2.11.tar.gz 
cd zlib-1.2.11
./configure
make
cd..
gcc bench_zlib.c  ./zlib-1.2.11/libz.a -O3 -o bench_zlib -DLOCAL_ZLIB
time ./bench_zlib SRR3744956_1.fastq.gz

这给出了

zlib version  1.2.11

real    0m5.236s
user    0m5.113s
sys 0m0.112s

我从本地源代码重新编译的版本慢了 40%。有什么解释吗?

事情已经检查过了:

有没有可能系统版本是用一些特殊的选项编译的,使它更快? (但是 40% 似乎很多,而且 zlib 库已经用 -O3 模式编译了)

正如 Mark Adler 在他的评论中所指出的,macOS 库中使用的代码必须不同。混淆来自于他们没有更改库版本字符串这一事实。

我猜他们使用类似于此版本的东西 https://github.com/jtkukunas/zlib (1.2.11.1-motley), where the CRC 计算是矢量化的。分析表明,与 zlib 1.2.11 相比,Apple zlib 版本中的 crc 函数快 9 倍。这种表现类似于 zlib "1.2.11.1-motley".

在一个 4GB 的 gzip 文件上,我有以下解压时间

apple zlib 1.2.11  (dynamic zlib included in Mac OS 10.13.6) :   47.9 s
vanilla zlib 1.2.11 (from zlib.net)                          :   70.8 s
zlib 1.2.11.1-motley (from github.com/jtkukunas/zlib)        :   48.4 s

此外,当使用 gzbuffer(testFile, 1 << 20); 将 zlib 缓冲区增加到 1MB 时,apple zlib 变得比 zlib 1.2.11.1-motley 快一点。

apple zlib 1.2.11    :   43.9 s
vanilla zlib 1.2.11  :   67.1 s
zlib 1.2.11.1-motley :   48.3 s

所以我猜想除了向量化的 CRC 之外,他们还有一些其他的优化。