2010-06-13 10 views
40

Je suis en train d'écrire une petite bibliothèque d'E/S pour vous aider dans un plus grand projet (passe-temps). Une partie de cette bibliothèque exécute diverses fonctions sur un fichier, qui est lu/écrit via l'objet FileStream. Sur chaque passe StreamReader.Read(...),E/S de fichiers avec flux - meilleure taille de mémoire tampon

Je déclenche un événement qui sera utilisé dans l'application principale pour afficher les informations de progression. Le traitement qui se passe dans la boucle est vaired, mais ne prend pas trop de temps (il peut s'agir d'une simple copie de fichier, par exemple, ou peut impliquer un cryptage ...).

Ma question principale est: Quelle est la meilleure taille de mémoire tampon à utiliser? En pensant aux mises en page de disques physiques, je pourrais choisir 2k, ce qui couvrirait une taille de secteur de CD et est un bon multiple d'un secteur de disque dur de 512 octets. Plus haut dans l'arbre d'abstraction, vous pouvez opter pour un tampon plus grand qui pourrait lire un cluster FAT entier à la fois. Je me rends compte avec les PC d'aujourd'hui, je pourrais aller pour une option plus affamée de mémoire (un couple de MiB, par exemple), mais ensuite j'augmente le temps entre les mises à jour et l'utilisateur perçoit une application moins réactive. En passant, j'espère pouvoir fournir une interface similaire aux fichiers hébergés sur des serveurs FTP/HTTP (sur un réseau local/DSL fastish). Quelle serait la meilleure taille de mémoire tampon pour ceux-ci (encore une fois, un compromis «meilleur cas» entre la réactivité perçue et la performance)?

+0

Cela peut être utile: http://stackoverflow.com/questions/19558435/what-is-the-best-buffer-size-when-using-binaryreader-to-read-big-files-1gb/19837238? noredirect = 1 # 19837238 –

Répondre

56

Les fichiers sont déjà mis en mémoire tampon par le cache du système de fichiers. Vous avez juste besoin de choisir une taille de buffer qui ne force pas FileStream à faire l'appel de Windows ReadFile() API natif pour remplir le buffer trop souvent. Ne pas aller en dessous d'un kilo-octet, plus de 16 Ko est un gaspillage de mémoire et hostile à la L1 cache du CPU (généralement 16 ou 32   Ko de données). KB est un choix traditionnel, même si cela ne couvrira exactement une page de mémoire virtuelle que par accident. Il est difficile de profiler; vous finirez par mesurer combien de temps il faut pour lire un fichier mis en cache. Ce qui fonctionne à des vitesses de RAM, 5 gigaoctets/s et plus si les données sont disponibles dans le cache. Il sera dans le cache la deuxième fois que vous exécuterez votre test, et cela n'arrivera pas trop souvent dans un environnement de production. Fichier I/O est complètement dominé par le lecteur de disque ou le NIC et est glacial lent, la copie des données est des cacahuètes. 4   KB fonctionnera bien.

+0

Des tailles de mémoire tampon faibles, par exemple de 4 à 8 ko, sont également préférables, car le cache du processeur peut contenir de telles quantités. Si vous allez à petit, vous pouvez accumuler des frais généraux importants à partir des transitions du noyau. – usr

+0

@HansPassant: Mon application traite beaucoup de petits fichiers ensemble ainsi que de gros fichiers séparément. Une taille de 4 Ko affectera-t-elle les performances pour les fichiers inférieurs à 4 Ko? –

+2

4 Ko est la valeur par défaut utilisée par .net framework: http://msdn.microsoft.com/en-us/library/dd783870.aspx – giammin

4

Lorsque je traite des fichiers directement via un objet de flux, j'utilise généralement 4096 octets. Il semble raisonnablement efficace sur plusieurs zones d'E/S (système de fichiers local, LAN/SMB, flux réseau, etc.), mais je ne l'ai pas profilé ou quoi que ce soit. Quand j'ai vu plusieurs exemples utiliser cette taille, et il est resté dans ma mémoire. Cela ne veut pas dire que c'est le meilleur.

+0

Droite. Je n'utiliserais jamais rien de moins que 4k, puisque c'est le plus petit bloc géré par le système de mémoire virtuelle (sur lequel le cache disque est basé). –

3

"Cela dépend".

Vous devrez tester votre application avec différentes tailles de mémoire tampon pour déterminer le meilleur résultat. Vous ne pouvez pas deviner à l'avance.