2010-11-04 4 views
1

Je dois lire un fichier texte volumineux (> 200 000 mots) et traiter chaque mot. Je lis dans le fichier entier dans une chaîne, puis attacher un flux de chaîne pour traiter facilement chaque mot. L'approche consiste à saisir directement chaque mot du fichier en utilisant << et à le traiter mais comparer les deux approches ne me donne aucun avantage en termes de temps d'exécution. N'est-il pas plus rapide d'utiliser une chaîne en mémoire que d'un fichier qui a besoin d'un appel système chaque fois que j'ai besoin d'un mot? S'il vous plaît suggérer des méthodes améliorant la performance.Performances des flux de chaînes par rapport aux flux d'E/S de fichiers en C++

+0

fait une mise en mémoire tampon interne. Fiddle avec la taille du tampon pour trouver un ajustement optimal. – codymanix

+0

Voir la réponse @Martin York ici pour une «chaîne du fichier» qui minimise la copie - http://stackoverflow.com/questions/132358/how-to-read-file-content-into-istringstream –

+0

J'étais sur le point de suggérer que . –

Répondre

1

La mise en cache est impliquée, donc elle n'effectue pas nécessairement un appel système à chaque extraction. Cela dit, vous pouvez obtenir des performances légèrement meilleures au moment de l'analyse en analysant un seul tampon contigu. D'un autre côté, vous êtes en train de sérialiser la charge de travail (lire le fichier entier, puis analyser), qui peut potentiellement être parallélisé (lire et analyser en parallèle).

1

La chaîne sera réaffectée et copiée énormément de fois pour accommoder 200 000 mots. C'est probablement ce qui prend le temps.

Vous devriez utiliser une corde si vous voulez créer une énorme chaîne en ajoutant.

+1

Cela pourrait devenir une bonne réponse si vous avez suggéré une solution. –

4

Si vous allez mettre les données dans un stringstream de toute façon, il est probablement un peu plus rapide et plus facile à copier directement à partir du flux d'entrée dans le flux de la chaîne:

std::ifstream infile("yourfile.txt"); 
std::stringstream buffer; 

buffer << infile.rdbuf(); 

Le ifstream utilisera un tampon Cependant, même si c'est probablement plus rapide que de lire une chaîne, puis de créer une chaîne, il ne sera peut-être pas plus rapide que de travailler directement à partir du flux d'entrée.

+3

Si d'autres E/S se déroulent parallèlement à ce traitement, la charge de données unique sera préférable car la tête de disque n'a pas la même possibilité de passer d'une actualisation de tampon à une autre. –

+0

@Steve: Je n'avais pas pensé à ça, mais c'est un bon point. –

+0

Je pense que cela combiné avec la réponse de Martin au q précédent sera le meilleur. Je vous ai donné +1 pour les meilleures infos locales –

4

Pour des performances et la copie minimum, cela est difficile à battre (aussi longtemps que vous avez assez de mémoire!):

void mapped(const char* fname) 
{ 
    using namespace boost::interprocess; 

    //Create a file mapping 
    file_mapping m_file(fname, read_only); 

    //Map the whole file with read permissions 
    mapped_region region(m_file, read_only); 

    //Get the address of the mapped region 
    void * addr  = region.get_address(); 
    std::size_t size = region.get_size(); 

    // Now you have the underlying data... 
    char *data = static_cast<char*>(addr); 

    std::stringstream localStream; 
    localStream.rdbuf()->pubsetbuf(data, size); 

    // now you can do your stuff with the stream 
    // alternatively 
} 
flux
Questions connexes