J'essaie de lire et d'écrire quelques mégaoctets de données stockées dans des fichiers, composée de 8 flotteurs convertis en cordes par ligne, à mon SSD.
Regardant le code C ++ et implémenter certaines des réponses ici pour la lecture et la rédaction de fichiers m'avèrent ce code pour la lecture d'un fichier: et ce code pour écrire des fichiers: P> stream.write(file.str().data(), file.tellg());
4 Réponses :
Dans votre échantillon, la partie lente est probablement les appels répétés à considérer un (Ceci est également une des raisons d'intention des jeux de la raison et de la mise en œuvre de la gestion de la mémoire personnalisée plutôt que de simplement Pour la lecture: lisez l'intégralité du fichier à la fois, si cela correspondra à la mémoire. P>
voir: Comment puis-je Lire un fichier entier dans une STD :: String en C ++? P>
Spécifiquement, voir le Si cela ne convient pas à la mémoire, gérez-le dans de gros morceaux. p>
Pour l'écriture: Construisez votre sortie dans un getline () code>. Bien que cela soit quelque peu dépendant de la mise en œuvre, généralement un appel à getline code> se résume à un appel d'exploitation pour récupérer la prochaine ligne de texte à partir d'un fichier ouvert. Les appels du système d'exploitation sont chers et doivent être évités dans des boucles serrées. p>
getline code> implémentation qui contient ~ 1 ms de frais généraux. Si vous l'appelez 1000 fois, chacun en lisant environ 80 caractères, vous avez acquis une seconde complète de frais généraux. Si, d'autre part, vous l'appelez une fois et lisez 80 000 caractères, vous avez supprimé 999 mètres de frais généraux et la fonction reviendra probablement presque instantanément. p>
MALLOC code> et neuf code> tout sur place.) p>
slurp code> répondre vers le bas. (Et prenez au cœur le commentaire sur l'utilisation d'un std :: vecteur code> au lieu d'un char [] code> tableau.) P>
Stringstream CODE> ou tampon similaire, puis écrivez-le d'une étape ou de gros morceaux pour minimiser le nombre de voyages ronds du système d'exploitation. p>
@ user11914177 Lire le fichier ASCII entier dans C ++ STD :: String
Donc, pour la lecture, j'ai une bonne amélioration, je reçois 180,6 Mo / s. Pour l'écriture, j'utilise déjà un flux de chaîne pour écrire dans le fichier.
@ user11914177 Ajoutez votre code mis à jour à votre question.
@ user11914177 Je penserai à cela. Se préparer pour un vol pour le moment. Je me demande si vous utilisez un std :: vecteur code> plutôt qu'un stringtream serait plus rapide. Je ne sais pas si stream.str () code> effectue toute conversion ou s'il renvoie simplement une référence à la ou les tampons internes du flux. Si elle convoque, cela générera des frais généraux pouvant être substantiels. Bonne chance!
@ 3Dave j'ai essayé l'exemple de vecteur et je n'ai que 26,3 Mo / s, cela semble donc être beaucoup plus lent
@ 3Dave pouvez-vous aider à ouvrir la question?
Vous pouvez essayer de copier le fichier entier à la fois et de voir si cela améliore la vitesse:
Vous ne pouvez pas simplement faire os << is.rdbuf () code> au lieu de std :: copier code>?
@MaximeGoruskin Oui, ça marche aussi. J'ai ajouté cela comme une alternative.
J'ai fait une nouvelle évaluation pour vous.
J'ai écrit un programme de test, qui crée d'abord un fichier de test. p>
Puis j'ai fait plusieurs méthodes d'amélioration: p>
redimensionner code> pour éviter les réaffectations li>
- La lecture du flux est considérablement améliorée en définissant une plus grande tampon d'entrée li>
ol>
S'il vous plaît voir et vérifier, si vous pouvez implémenter une de mes idées pour votre solution p>
edit p> P> P> Programme de test à la lecture pure: p> xxx pré> avec celui que je fais 123,2 Mo / s p> p> P>
Si je n'ai pas fait des erreurs, vous lisez à 37,5 Mb / s. C'est une amélioration, mais c'est toujours assez lent.
HM, 52,4 Mo / S sur ma machine. Mais faire beaucoup d'autres choses dans mon exemple de code. . . Mais je comprends. Je vais éditer et dénicher mon code d'exemple
Merci pour votre code raccourci, aussi loin que j'ai lu d'autres réponses, std :: copy (STD :: istreambuf_iterator readbuf () code> de ifstream code>. Les vitesses sont similaires. Pouvez-vous aider à la réouverture de la question?
On dirait que vous émettez des nombres formatés dans un fichier. Il existe déjà deux goulots d'étranglement: formater les numéros en forme lisible humaine et le fichier E / S. p>
Les meilleures performances que vous pouvez réaliser sont de conserver les données fluides. Démarrer et arrêter nécessite des pénalités générales. p>
Je recommande la double tampon avec deux fils ou plus. p>
Un thread formate les données dans un ou plusieurs tampons. Un autre thread écrit les tampons au fichier. Vous devrez régler la taille et la quantité de tampons pour conserver les données qui circulent. Lorsqu'un thread finit un tampon, le fil commence à traiter un autre tampon.
Par exemple, vous pouvez utiliser l'utilisation de l'écriture Le double tampon avec des filets peut également être adapté pour la lecture. Un thread lit les données du fichier en un ou plusieurs tampons et un autre thread formate les données (à partir des tampons) en format interne. p> fstream.write () code> pour écrire tout le tampon. p>
Me semble que c'est io lié.
@ 3Dave Oui, écrire dans les fichiers est E / S Lié, par sa nature même. Les E / S sont l'un des goulots d'étranglement plus lents pour un programme. L'objectif est de garder le streaming de données.
Mon point était que, si l'IO est le goulot d'étranglement, les threads ne fourniraient aucune prestation de perf. Si la CPU est affamée, ce serait une question différente.
Serialize vos données et écrivez tout cela dans une commande en mode binaire.
Est-ce que cela répond à votre question? Lecture rapide du fichier texte en C ++
@AYXAN Ceci utilise Boost ou Bibliothèques système. Je veux que STL seulement
@ user11914177 Pas toutes les réponses. En outre, vous devriez probablement commencer une prime sur cette question et préciser vos contraintes.
"Grandes quantités" mais à quel point? 1 Go ou 1 To? Et écrivez-vous à plusieurs fichiers ou juste un seul fichier? Quelles sont les propriétés du fichier d'entrée? Sont les lignes longues ou courtes? Il y a beaucoup de facteurs qui affectent la vitesse de lecture / écriture que vous n'avez pas montrée. Mais la première chose à faire est d'augmenter la taille de la mémoire tampon
@Pluclv utilisant probablement des "quantités assez grandes" a fait ce son aussi grand (je ne suis pas un expert en tailles de données de nommage). J'ai mis à jour la question pour ajouter encore plus de détails.
Serait-il plus précis de dire que vous copiez des fichiers texte, puisque vos exemples de lecture et d'écriture ont lu / écriture par ligne et ignorez le contenu? Sur Linux, vous ne pouvez probablement pas battre
sendfile code> a>.Comment mesurez-vous les vitesses? Publiez le code complet de votre repère, voir Stackoverflow.com/help/minimal-reproductible-example
@MaximeGoruskkin Pourquoi y a-t-il toujours un gars qui pose des questions complètement non pertinentes? Mais de toute façon, vous avez votre réponse
@ user11914177 Ce mec est là pour aider cet autre gars qui pense qu'il sait tout sauf des erreurs stupides.