2010-05-14 4 views
3

Je fais des choses liées à l'analyse de gros globs de fichiers texte, et je testais quelle méthode d'entrée utiliser.zlib gzgets extrêmement lent?

Il n'y a pas beaucoup de différence en utilisant C++ std :: ifstreams vs c FICHIER,

Selon la documentation de zlib, il prend en charge les fichiers non compressés, et lit le fichier sans décompression.

Je vois une différence de 12 secondes à l'aide non zlib à plus de 4 minutes en utilisant zlib.h

Ce que j'ai testé plusieurs pistes à faire, il est donc pas un problème de cache disque. Est-ce que j'utilise zlib dans un sens ou dans l'autre?

grâce

#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

side note - 'argv [2]' est généralement une chaîne. comment faites-vous que ce soit «0», «1» ou «2»? êtes vous vraiment? – shoosh

+0

remarquez l'atoi. Im l'exécution du programme avec temps ./a.out FICHIER 0 ou temps ./a.out FICHIER 1 ou temps ./a.out FILE 2 – monkeyking

+0

Je viens d'essayer zlib-1.2.5. Sur un fichier gzip particulier, gzgetc et gzgets sont 10 fois plus rapides que ceux de 1.2.3. Habituellement, j'emballe les fonctions gz * avec mes propres E/S tamponnées. Il semble que je n'ai plus besoin de ce wrapper. – user172818

Répondre

3

Je suppose que vous utilisez zlib-1.2.3. Dans cette version, gzgets() appelle virtuellement gzread() pour chaque octet. Appeler gzread() de cette façon a une grosse surcharge. Vous pouvez comparer l'heure du CPU d'appeler gzread (gzfp, buffer, 4096) une fois et d'appeler gzread (gzfp, buffer, 1) pendant 4096 fois. Le résultat est le même, mais le temps CPU est extrêmement différent. Ce que vous devez faire est de mettre en œuvre des E/S tamponnées pour zlib, en lisant ~ 4 Ko de données dans un morceau avec un appel gzread() (comme ce que fait fread() pour read()). Le dernier zlib-1.2.5 est dit être significativement amélioré sur gzread/gzgetc/.... Vous pouvez essayer aussi. Comme il est sorti très récemment, je n'ai pas essayé personnellement.

EDIT:

J'ai essayé zlib-1.2.5 tout à l'heure. gzgetc et gzgets dans 1.2.5 sont beaucoup plus rapides que ceux de 1.2.3.

Questions connexes