2010-07-21 5 views
2

Nous avons une classe Log qui écrit des entrées de journal dans un fichier journal via StreamWriter. Chaque fois que son logItem() est appelée, une entrée est transmise et écrit dans le fichier. À l'heure actuelle, après l'appel de la méthode WriteLine(), un Flush() est également appelé.Impact des performances d'appel de StreamWriter flush()

Pensez-vous qu'il est nécessaire d'appeler Flush() pour chaque écriture? un impact sur les performances?

Répondre

0

EDIT:
Ceci est pour les très anciennes versions de .net framework. voir les commentaires

Cela réduira beaucoup les performances.
Il est toujours préférable d'utiliser AutoFlush, car il est optimisé et rapide, et n'a pas besoin de beaucoup de code pour faire le travail.

si vous ne comptez pas utiliser autoflush, chasse d'eau tous les 50 ou 60 lignes vous donnera de meilleures performances, mais le nombre dépend de la longueur de ligne (généralement 4 Ko est OK pour chaque chasse d'eau)

une meilleure manière est d'utiliser un protocole binaire et utilise du code pour le lire, c'est toujours plus rapide sans condition.

+0

Réduit pour informations incorrectes. Documentation - https://msdn.microsoft.com/en-us/library/system.io.streamwriter.autoflush%28v=vs.110%29.aspx - indique qu'appeler explicitement Flush donnera de meilleures performances que l'utilisation d'AutoFlush . – yoyo

+0

@yoyo Citation de votre référence: Lorsque AutoFlush est défini sur false, StreamWriter effectue une quantité limitée de mise en mémoire tampon, à la fois interne et potentiellement dans l'encodeur, à partir de l'encodage que vous avez transmis. il a l'habitude de SUCK CPU. – Behrooz

+1

Salut @Behrooz - la phrase que vous avez citée est immédiatement suivie de "Vous pouvez obtenir de meilleures performances en définissant AutoFlush sur false", ce qui contredit directement votre affirmation selon laquelle "Il est toujours préférable d'utiliser AutoFlush, car il est optimisé et rapide." (Peut-être devriez-vous modifier votre réponse pour indiquer qu'elle ne s'applique qu'à une version antérieure de .NET?) – yoyo

6

De toute évidence, il y a un impact sur les performances. La vraie question est, est-il assez d'un impact de la performance à l'importance. Et (bien que nous ne puissions pas vraiment dire de votre question) le plus probable il n'y a pas.

Cela dépend vraiment du nombre de lignes écrites dans le journal et de l'importance de l'écriture dans le flux (un système de fichiers plus rapide sera moins coûteux). La seule façon de savoir est de le tester, dans les conditions que vous attendez qu'il fonctionne.

Si nécessaire pour appeler Flush() dépend de la mise à jour dont vous avez besoin le journal à être. Si vous craignez de perdre des données si le système tombe en panne, vous devez l'appeler souvent (en particulier si le journal va être utilisé pour aider à déboguer les plantages). Un compromis pourrait être de garder un compteur et vider le journal toutes les 4 ou 5 lignes ou plus.

En bref: Je continuerais à vider les données à chaque ligne, pour l'instant. Une fois que vous avez terminé le programme, vous pouvez profiler le code pour voir ce qui le fait fonctionner lentement. Si c'est le journal, puis vous inquiétez de le rendre plus rapide. Pas avant.

1

Eh bien, l'appel à Flush fait exactement ce qu'il dit. Les flux tamponneront les informations pour des raisons de performance; le plus souvent, il est plus facile d'obtenir des paquets plus gros d'octets, puis d'écrire cela sur la ressource sous-jacente (disque, réseau) que d'écrire à la ressource sous-jacente à chaque fois. Calling Flush fera en sorte que tout ce qui est tamponné soit écrit dans la ressource sous-jacente.

Si vous appelez ceci après chaque écriture, vous verrez probablement une diminution des performances, car vous faites beaucoup de petites écritures à ce que je suppose être le disque. L'avantage ici est qu'il est plus tolérant aux pannes. Si quelque chose se bloque, votre journal sera aussi à jour que possible.

Si vous n'appelez pas Flush après chaque écriture dans le journal, vous courez le risque de perdre certaines de ces informations en cas de défaillance.Maintenant, que le compromis soit nécessairement bon ou non, vous devez mesurer l'impact de l'appel de Flush soit tout le temps, ou à d'autres moments, et si oui ou non il répond à vos risques et besoins de performance.

+0

Ou vous pouvez utiliser quelque chose comme "BeginCriticalOperation" pour activer le flush à chaque fois. – Behrooz

+0

@Behrooz Pourriez-vous s'il vous plaît expliquer "BeginCriticalOperation". –

+0

@chibacity: oui, je veux dire que nous pouvons changer l'intervalle de Flush (1 ou 50 par exemple) avec deux procédures: BeginCriticalOperation pour définir l'intervalle à 1, et EndCriticalOperation pour régler l'intervalle à son état normal.it aura de meilleures performances avec un peu plus code. – Behrooz

2

Les performances de ce problème peuvent facilement être testées. Le vidage aura un impact sur les performances, mais il n'entraînera pas forcément l'écriture immédiate du contenu sur le disque (impact potentiel le plus important sur les performances) sauf si vous avez spécifié FileOptions.WriteThrough ou si le système d'exploitation a été configuré pour ne pas utiliser write-caching pour le disque cible. Si FileOptions.WriteThrough n'a pas été spécifié, les données seront écrites dans le cache de disque du système d'exploitation (c'est-à-dire dans la mémoire), puis écrites sur le disque par le système d'exploitation à un moment ultérieur, c'est-à-dire de manière asynchrone.

Ainsi, même s'il existe des problèmes de performances potentiels, ceux-ci peuvent être atténués dans une certaine mesure par le cache de disque du système d'exploitation qui tamponnera les écritures et les validera ultérieurement. Toutefois, cela entraîne des problèmes de fiabilité, car les entrées de journal non validées peuvent être perdues si l'application se bloque.

Vous devez équilibrer les performances avec les besoins de fiabilité.

Les caractéristiques de performance réelles dépendent en grande partie de vos: matériel, de votre environnement \ de vos paramètres et de votre comportement de journalisation. Testez d'abord les performances, puis réfléchissez à des optimisations simples s'il existe réellement un problème, par exemple. ne rincer qu'après tant de lignes, en tenant compte des problèmes de fiabilité.

"Ne pensez pas - mesurez".

Questions connexes