2009-03-15 4 views
5

La situation est la suivante: il existe un fichier avec 14 294 508 entiers non signés et 13 994 397 nombres à virgule flottante (besoin de lire double s). La taille totale du fichier est ~ 250 Mo.Comment effectuer une entrée formatée rapide à partir d'un flux en C++?

L'utilisation de std::istream prend ~ 30sec. Lire les données du fichier en mémoire (il suffit de copier les octets, sans entrée formatée) est beaucoup plus rapide. Est-il possible d'améliorer la vitesse de lecture sans changer le format de fichier?

+0

Je pense que vous devriez publier votre code de boucle – Ben

+0

S'il s'agit de bibliothèques MSVC, vous voudrez peut-être rechercher le montant de pénalité que vous recevez de SECURE_SCL (activé par défaut). Prenez soin de comprendre les implications de l'éteindre, cependant. – Functastic

+0

Désolé, cela devrait être: _SECURE_SCL – Functastic

Répondre

3

Avez-vous besoin d'utiliser des E/S de style STL? Vous devez vérifier this excellent morceau de travail de l'un des experts. C'est un spécialiste iostream par Dietmar Kuhl.

Je déteste suggérer cela, mais jetez un oeil sur les routines d'E/S au format C. Aussi, lisez-vous tout le dossier en une fois?

+0

La syntaxe et l'approche n'a pas d'importance :) Et oui, je suis en train de lire le fichier entier. –

+0

Avez-vous essayé fscanf et vos amis? Je dirais donner un coup de feu, et mesurer. – dirkgently

1

Vous pouvez également consulter la bibliothèque de FastFormat de Matthew Wilson:

Je ne l'ai pas utilisé, mais il rend certaines revendications assez impressionnant et je l'ai trouvé beaucoup de son autre travail pour être utile d'étudier et d'utiliser (et de voler à l'occasion).

+0

Supporte-t-il l'entrée formatée? –

+0

Merde - vous avez raison ... C'est le formatage de sortie seulement. –

+0

Peut-être que les techniques peuvent être appliquées à l'entrée – dcw

1

Vous n'avez pas spécifié le format. Il est possible que vous puissiez le mapper en mémoire, ou que vous puissiez le lire en très gros morceaux et le traiter dans un algorithme batch.

En outre, vous n'avez pas dit si vous savez avec certitude que le fichier et le processus qui le lira seront sur la même plate-forme. Si un processus big-endian l'écrit et qu'un processus little-endian le lit, ou vice versa, il ne fonctionnera pas.

1

L'analyse de l'entrée par vous-même (atoi & atof) augmente généralement la vitesse au moins deux fois, par rapport aux méthodes de lecture "universelles".

0

quelque chose de rapide et sale est de vider tout le fichier dans une chaîne standard ++ C, puis utiliser un stringstream dessus:

#include <sstream> 
// Load file into string file_string 
std::stringstream s(file_string); 
int x; float y; 
s >> x >> y; 

Ce ne peut pas vous donner beaucoup d'une amélioration de la performance (vous obtiendrez une accélération plus importante en évitant les flux internes), mais c'est très facile à essayer, et cela peut être plus rapide.