Quelle est la meilleure taille de mémoire tampon lors de l’utilisation de BinaryReader pour lire des fichiers volumineux (> 1 Go)?

Je lis des fichiers binarys et voici un exemple:

public static byte[] ReadFully(Stream input) { byte[] buffer = new byte[16*1024]; int read; while ((read = input.Read(buffer, 0, buffer.Length)) > 0) { ...... } } 

De toute évidence, la taille de la mémoire tampon (16 * 1024) joue un grand rôle dans les performances. J’ai lu que cela dépend de la technologie d’E / S ( SATA , SSD , SCSI , etc.) et aussi de la taille de fragment de la partition dont le fichier existe (on peut définir lors du formatage de la partition).

Mais voici la question: Existet-il une formule ou une meilleure pratique pour définir la taille du tampon? En ce moment, je définis sur la base d’essais et d’erreurs.

Edit: J’ai testé l’application sur mon serveur avec différentes tailles de mémoire tampon, et j’ai les meilleures performances avec 4095 * 256 * 16 (16 Mo) !!! 4096 est 4 secondes plus lent.

Voici quelques anciens messages qui sont très utiles mais je ne peux toujours pas en comprendre la raison:

  • BinaryReader plus rapide (dangereux) dans .NET

  • Taille de lecture optimale du tampon de fichier?

  • E / S de fichier avec stream – meilleure taille de la mémoire tampon

  • Comment déterminez-vous la taille de la mémoire tampon idéale lorsque vous utilisez FileInputStream?

” Modèles et performances de programmation de fichiers séquentiels avec .NET ” est un excellent article sur l’amélioration des performances d’E / S.

À la page 8 de ce fichier PDF, il est indiqué que la bande passante pour une taille de mémoire tampon supérieure à huit octets est constante. Considérez que l’article a été écrit en 2004 et que le disque dur est ” Maxtor 250 Go 7200 RPM SATA ” et que le résultat devrait être différent selon les dernières technologies d’E / S.

Si vous recherchez les meilleures performances, consultez pinvoke.net ou la page 9 du fichier PDF, les mesures de performances des fichiers non tamponnés donnent de meilleurs résultats:

Dans les E / S sans tampon, les données du disque se déplacent directement entre l’espace adresse de l’application et le périphérique sans aucune copie intermédiaire.

Résumé

  • Pour les disques simples, utilisez les parameters par défaut du framework .NET – ils offrent d’excellentes performances pour l’access séquentiel aux fichiers.
  • Pré-allouer des fichiers séquentiels volumineux (en utilisant la méthode SetLength ()) lors de la création du fichier. Cela améliore généralement la vitesse d’environ 13% par rapport à un fichier fragmenté.
  • Au moins pour le moment, les baies de disques requièrent des E / S non tamponnées pour atteindre les performances les plus élevées – les E / S mises en mémoire tampon peuvent être huit fois plus lentes que les E / S sans tampon. Nous nous attendons à ce que ce problème soit traité dans les versions ultérieures du framework .NET.
  • Si vous faites votre propre mise en mémoire tampon, utilisez de grandes tailles de requêtes (64 Ko est un bon sharepoint départ). En utilisant le framework .NET, un seul processeur peut lire et écrire une grappe de disques à plus de 800 Mo / s en utilisant des E / S non tamponnées.

Il n’y a pas de meilleure ou de pire taille de tampon, mais vous devez examiner certains aspects.

Comme vous utilisez C #, et que vous utilisez Windows, Windows utilise NTFS et sa taille de page est de 4 Mo. Il est donc conseillé d’utiliser des multiples de 4096. Votre taille de mémoire tampon est donc 16*1024 = 4*4096 . bon choix, mais pour dire si c’est mieux ou pire que 16*4096 on ne peut pas dire.

Tout dépend de la situation et des exigences du programme. Rappelez-vous ici que vous ne pouvez pas choisir la meilleure option, mais seulement certaines meilleures. Je recommande d’utiliser 4096 , mais vous pouvez également utiliser votre propre 4*4096 ou même 16*4096 , mais rappelez-vous que ce tampon sera alloué sur le tas, son allocation prend un certain temps, vous ne voulez donc pas allouer un gros tampon, par exemple 128*4096 .