Question

On m'a informé que ma bibliothèque est plus lente que prévu, de l'ordre de plus de 30 fois trop lente pour l'analyse d'un fichier particulier (fichier texte, taille 326 ko). L'utilisateur a suggéré que j'utilise peut-être std :: ifstream (probablement au lieu de FILE ).

Je préférerais ne pas réécrire à l'aveuglette. Je pensais donc vérifier ici en premier, car je suppose que le goulot d'étranglement est ailleurs. Je lis caractère par caractère, si bien que les seules fonctions que je suis sont get () , peek () et tellg () / seekg () .

Mise à jour:

J'ai profilé et obtenu un sortie déroutante - gprof n'a pas semblé penser qu'il en avait fallu de même longue. J'ai réécrit le programme pour lire le fichier entier dans un tampon en premier, et il a accéléré d'environ 100x. Je pense que le problème peut avoir été le tellg () / seekg () qui a pris beaucoup de temps, mais gprof n'a peut-être pas été capable de le voir pour une raison quelconque. Dans tous les cas, ifstream ne n'apparaît pas pour mettre en mémoire tampon le fichier entier, même pour cette taille.

Était-ce utile?

La solution

Je ne pense pas que cela ferait une différence. Surtout si vous lisez caractère par caractère, les frais généraux des E / S risquent de dominer complètement autre chose . Pourquoi lisez-vous les octets simples à la fois? Vous savez à quel point c'est inefficace?

Sur un fichier de 326 Ko, la solution la plus rapide sera probablement de le lire en mémoire à la fois.

La différence entre std :: ifstream et les équivalents C est essentiellement un appel de fonction virtuelle ou deux. Cela peut faire une différence s’il est exécuté quelques dizaines de millions de fois par seconde, sinon, pas vraiment. Les entrées / sorties de fichiers sont généralement si lentes que l'API utilisée pour y accéder importe peu. Ce qui compte beaucoup plus, c’est le modèle lecture / écriture. Beaucoup de recherches sont mauvaises, les lectures / écritures séquentielles sont bonnes.

Autres conseils

Cela devrait être un peu plus lent, mais comme ce que vous avez dit, ce n’est peut-être pas le goulot d’étranglement. Pourquoi ne profilez-vous pas votre programme et voyez si c'est le cas?

Je pense qu'il est peu probable que votre problème soit résolu en passant de fstream à FILE *, les deux étant généralement protégés par la bibliothèque C. De plus, le système d'exploitation peut mettre en cache les lectures (linux est très performant à cet égard). Étant donné la taille du fichier auquel vous accédez, il est fort probable qu'il sera entièrement en RAM.

Comme PolyThinker dit que votre meilleur pari est d'exécuter votre programme via un profileur et de déterminer où se situe le problème.

Vous utilisez également seekg / tellg, cela peut entraîner des retards importants si votre disque est fortement fragmenté, car pour lire le fichier pour la première fois, le disque doit déplacer les têtes à la bonne position.

Tous les repères sont diaboliques. Décrivez simplement votre code pour les données que vous attendez.

J'ai effectué une comparaison des performances d'E / S entre Ruby, Python, Perl et C ++ une fois. Pour mes données, versions de langages, etc. La variante de C ++ a été plusieurs fois plus lente (c'était une grosse surprise à cette époque).

Je suis d'accord que vous devriez profiler. Mais si vous lisez le fichier un caractère à la fois, pourquoi ne pas créer un fichier mappé en mémoire? De cette façon, vous pouvez traiter le fichier comme un tableau de caractères et le système d’exploitation doit s’occuper de la mise en mémoire tampon de bas niveau pour vous. La solution la plus simple et probablement la plus rapide est une victoire dans mon livre. :)

Ici est un excellente référence qui montre que dans des conditions extrêmes, les fstream sont en réalité assez lents ... sauf si:

  1. Vous utilisez la mise en mémoire tampon (je ne saurais trop insister là-dessus)
  2. Vous manipulez le tampon vous-même (c'est-à-dire si vous avez besoin de performances telles que OP dans la question liée), ce qui n'est pas si différent de l'utilisation de FILE * .

Cependant, vous ne devriez pas optimiser prématurément. Les fstreams sont généralement meilleurs, et si vous devez les optimiser plus tard, vous pouvez toujours le faire plus tard, à moindre coût. Afin de préparer le pire à l’avance, je suggère de créer un proxy minimal pour fstream afin que vous puissiez l’optimiser plus tard, sans rien toucher d’autre.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top