2010-05-14 2 views
3

Я делаю вещи, связанные с разбором огромных глобусов текстовых файлов, и тестировал, какой метод ввода использовать.zlib gzgets чрезвычайно медленный?

Существует не так много разницы, используя C++ станд :: ifstreams против C File,

Согласно документации Zlib, он поддерживает несжатые файлы, и будет читать файл без декомпрессии.

Я вижу разницу от 12 секунд с использованием не Zlib более 4 минут с помощью zlib.h

В этом я протестированные делать несколько прогонов, поэтому его не проблема дискового кэша.

Я использую 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]); 

} 
+0

сторона примечание - 'argv [2]' обычно строка. как вы делаете это '0',' 1' или '2'? вы действительно? – shoosh

+0

обратите внимание на atoi. Im запустить программу с времени ./a.out FILE 0 или время ./a.out ФАЙЛ 1 или время ./a.out FILE 2 – monkeyking

+0

Я просто попытался Zlib-1.2.5. В определенном файле gzip gzgetc и gzgets работают на 10 раз быстрее, чем в 1.2.3. Я обычно обертываю функции gz * своим собственным буферизированным вводом-выводом. Кажется, мне больше не нужна эта обертка. – user172818

ответ

3

Я предполагаю, что вы используете Zlib-1.2.3. В этой версии gzgets() фактически вызывает gzread() для каждого байта. Вызов gzread() таким образом имеет большие накладные расходы. Вы можете сравнить процессорное время вызова gzread (gzfp, buffer, 4096) один раз и вызова gzread (gzfp, buffer, 1) в течение 4096 раз. Результат тот же, но время CPU сильно отличается.

Что вам нужно сделать, это реализовать буферизованный ввод-вывод для zlib, считывая данные размером 4 КБ в куске с помощью одного вызова gzread() (например, что делает fread() для read()). Говорят, что последний zlib-1.2.5 значительно улучшен на gzread/gzgetc/.... Вы также можете попробовать это. Поскольку он выпущен совсем недавно, я не пробовал лично.

EDIT:

Я попытался Zlib-1.2.5 только сейчас. gzgetc и gzgets в 1.2.5 намного быстрее, чем в 1.2.3.

Смежные вопросы