3

テキストファイルの巨大なグロブの解析に関連することを行っており、使用する入力方法をテストしていました。

c++ std::ifstreams と c FILE を使用しても大きな違いはありません。

zlib のドキュメントによると、非圧縮ファイルをサポートしており、解凍せずにファイルを読み取ります。

非 zlib を使用した場合の 12 秒と、zlib.h を使用した場合の 4 分以上の差が見られます。

これは複数回実行してテストしたので、ディスクキャッシュの問題ではありません。

zlib を間違った方法で使用していますか?

ありがとう

#include <zlib.h>
#include <cstdio>
#include <cstdlib>
#include <fstream>
#define LENS 1000000


size_t fg(const char *fname){
  fprintf(stderr,"\t-> using fgets\n");
  FILE *fp =fopen(fname,"r");
  size_t nLines =0;
  char *buffer = new char[LENS];
  while(NULL!=fgets(buffer,LENS,fp))
    nLines++;

  fprintf(stderr,"%lu\n",nLines);
  return nLines;
}

size_t is(const char *fname){
  fprintf(stderr,"\t-> using ifstream\n");
  std::ifstream is(fname,std::ios::in);
  size_t nLines =0;
  char *buffer = new char[LENS];
  while(is. getline(buffer,LENS))
    nLines++;

  fprintf(stderr,"%lu\n",nLines);
  return nLines;
}

size_t iz(const char *fname){
  fprintf(stderr,"\t-> using zlib\n");
  gzFile fp =gzopen(fname,"r");
  size_t nLines =0;
  char *buffer = new char[LENS];
  while(0!=gzgets(fp,buffer,LENS))
    nLines++;

  fprintf(stderr,"%lu\n",nLines);
  return nLines;
}

int main(int argc,char**argv){
  if(atoi(argv[2])==0)
    fg(argv[1]);
  if(atoi(argv[2])==1)
    is(argv[1]);
  if(atoi(argv[2])==2)
    iz(argv[1]);

}
4

1 に答える 1

3

zlib-1.2.3 を使用していると思います。このバージョンでは、gzgets() は事実上、各バイトに対して gzread() を呼び出しています。このように gzread() を呼び出すと、オーバーヘッドが大きくなります。gzread(gzfp, buffer, 4096) を 1 回呼び出した場合と、gzread(gzfp, buffer, 1) を 4096 回呼び出した場合の CPU 時間を比較できます。結果は同じですが、CPU 時間は大きく異なります。

あなたがすべきことは、zlib のバッファリングされた I/O を実装し、1 回の gzread() 呼び出しでチャンク内の ~4KB のデータを読み取ることです (fread() が read() に対して行うことと同様)。最新の zlib-1.2.5 は、gzread/gzgetc/... で大幅に改善されていると言われています。それも試してみてください。最近発売されたので、個人的には試していません。

編集:

今zlib-1.2.5を試しました。1.2.5 の gzgetc と gzgets は、1.2.3 のものよりもはるかに高速です。

于 2010-05-14T21:09:35.437 に答える