J'essaie de mettre en œuvre une méthode de filecopy pouvant correspondre à la performance une copie effectuée avec l'Explorateur Windows.
Pour exemple une copie (avec l'explorateur Windows) de notre NAS à mon ordinateur, effectue plus de 100 Mo. . P>
Mon implémentation actuelle fait la même copie à environ 55 Mo / sec, qui est déjà meilleur que le système.IO.File.copy () qui fonctionne à 29 Mo / sec. P>
static void Main(string[] args)
{
String src = @"";
String dst = @"";
Int32 buffersize = 1024 * 1024;
FileStream input = new FileStream(src, FileMode.Open, FileAccess.Read, FileShare.None, 8, FileOptions.Asynchronous | FileOptions.SequentialScan);
FileStream output = new FileStream(dst, FileMode.CreateNew, FileAccess.Write, FileShare.None, 8, FileOptions.Asynchronous | FileOptions.SequentialScan);
Int32 readsize = -1;
Byte[] readbuffer = new Byte[buffersize];
IAsyncResult asyncread;
Byte[] writebuffer = new Byte[buffersize];
IAsyncResult asyncwrite;
DateTime Start = DateTime.Now;
output.SetLength(input.Length);
readsize = input.Read(readbuffer, 0, readbuffer.Length);
readbuffer = Interlocked.Exchange(ref writebuffer, readbuffer);
while (readsize > 0)
{
asyncwrite = output.BeginWrite(writebuffer, 0, readsize, null, null);
asyncread = input.BeginRead(readbuffer, 0, readbuffer.Length, null, null);
output.EndWrite(asyncwrite);
readsize = input.EndRead(asyncread);
readbuffer = Interlocked.Exchange(ref writebuffer, readbuffer);
}
DateTime Stop = DateTime.Now;
TimeSpan Duration = Stop - Start;
Double speed = input.Length / Duration.TotalSeconds; // bytes/s
System.Console.WriteLine("MY Speed : " + (speed / 1024 / 1024).ToString() + " mo/sec");
input.Close();
output.Close();
System.IO.File.Delete(dst);
}
6 Réponses :
Essayez de changer la taille du tampon pour égaler la taille du secteur sur le disque dur - probable 4 Ko. Utilisez également la classe System.Diagnostics.stopwatch pour le moment chronométrage. P>
Je n'aurais pas non plus la peine d'utiliser les méthodes asynchrones dans une boucle serrée - elle entraînera une augmentation des frais généraux et alloue un fil de la piscine pour faire le travail. P>
Encore une fois, utilisez le à l'aide de la relève code> pour gérer la disposition de vos flux. Notez cependant que cela inclinera votre synchronisation car vous disposez actuellement des objets après avoir arrêté la minuterie. P>
Les petits multiples de tailles sectorielles fonctionnent également bien ... Testez tout de 1x à 16 fois peut montrer un gain important dans l'un d'entre eux.
Fais seule une lecture synchrone n'a fourni aucune meilleure performance.
Je ne suis pas sûr de lire à partir du flux et de l'écriture à un autre courant de manière asynchrone en même temps, c'est plus rapide non plus. Vous seriez biché des E / S avec deux tâches en même temps. Pour les fichiers plus petits, avez-vous essayé de lire le lot dans la RAM puis de l'écrire? De plus, vous pouvez écrire dans des morceaux de gros morceaux ou tous à la fois, la tampon n'est donc pas strictement nécessaire.
Il existe des suspects habituels pour augmenter la vitesse sur un réseau: p>
Autre que cela, vous êtes à la merci de vos limitations matérielles. P>
Plusieurs threads de téléchargement ne fonctionnaient que si le goulot d'étranglement n'était pas l'E / S, ce qui est probablement.
@Adam - Ce pourrait être le réseau, auquel cas il serait capable d'augmenter légèrement la perfection. Comme pour tout ce qui est lié à Perf, cependant, il s'agit de tester et de mesurer les différentes techniques.
Avez-vous essayé plus petit em> tailles de tampon? Une taille tampon de 1 Mo est terriblement énorme et normalement tampon de 4-64kb vous donne la meilleure performance. P>
En outre, cela peut être lié à votre question: Comment écrire un code de diffusion de fichiers super-rapide en C #? P>
Et peut-être que vous pouvez améliorer les performances à l'aide de fichiers mappés de mémoire: http://weblogs.asp.net/gunnarpeipman/archive/2009/06/21/net-Framework-4-0-Autilisateur-Memory-Memory-Files-Files. ASPX P>
L'utilisation d'une taille de tampon de 64 kb rend la copie aller plus lente d'environ 46 Mo / sec.
Donc, jusqu'à 2 Mo, 4 Mo, ou plus Augmente Performancefurther? La performance augmente-t-elle de 64 à 128? Peut-être qu'il y a un beespot entre 64k et 1MB où la performance est optimale?
Après 256kb, il ne semble pas y avoir d'augmentation de la performance, toujours environ 60 Mo / sec.
fichier.copy () code> appelle simplement le fichier copyfile () code> API, vous pouvez essayer p / invoke shfileoperation () code> qui est ce qui est quoi la coque utilise - il semble souvent plus rapide. P>
Cela pourrait être une option si je copie seulement un fichier, mais je dois également être capable d'écrire la sortie sur plusieurs destinations.
Pour une compréhension plus profonde des options de conception et des compromis impliqués dans la copie de fichiers, avec et sans actions réseau, je vous suggère de regarder Mark Russinovich's Blog Post Il y a quelques années. Il y a beaucoup plus de rides impliquées que de la tailles du secteur du disque dur, par exemple ... p>
probablement la seule option plus rapide utiliserait un De cette façon, vous devez aligner la taille de la mémoire tampon avec la taille du secteur du système de fichiers, etc. p>
Ce serait nettement plus rapide - surtout dans Windows XP. P>
BTW. J'ai atteint ~ 400 Mo de bande passante sur un tableau à rayures 0 de cette façon (en utilisant 4 Mo tampon). P> absorbé IO code>: Fonction ReadFile , Fonction CreateFile , Fonction Writefile avec le File_flag_no_buffering code> drapeau avec 2-6 MB tampon. P>
Comment l'aide d'E / S désolérait-elle avec le stockage NAS? Les coûts d'accès au réseau et de disque dur domineraient. L'élimination de la mémoire tampon pourrait très bien ralentir les performances, lorsque plusieurs goulots d'étranglement sont présents.
Je n'ai pas remarqué la partie NAS. Vous n'éliminez que la mise en mémoire tampon automatique par le système. Vous tamponnez toujours les données mais vous choisissez la taille de la mémoire tampon. Pour les disques lents, cela n'a pas beaucoup, mais pour les matrices RAID rapides et les réseaux de tubercules de la performance absorbée IO sont très perceptibles - sans parler de cela est facile sur la CPU. Je ne l'utilise pas si je n'ai pas besoin de la manipulation de Winapi. Quoi qu'il en soit, vous pouvez utiliser IO non coupé avec NAS.
Après avoir finalement été entré dans le lapin entier (chevauchement + IO non coupé), je peux confirmer que c'est le seul moyen d'obtenir de véritables performances. Vous avez 2,25 gibr / sec sur un lien Dual 10g (Merci SMB3) lors de la lecture d'une échelle NAS.
Windows Explorer peut également exploiter le cache du système de fichiers et afficher un transfert de 100 Mo / SEC, mais le noyau peut ne pas avoir écrit le fichier entier sur le disque, ce faisant ainsi en arrière-plan une fois l'opération terminée. À quelle vitesse pouvez-vous lire le fichier entier dans une mémoire Morthstream?
Est-ce vraiment 100 Mbps b> ou 100 Mbps b> (grande différence là-bas)? Si c'est 100 MBPS, c'est un NAS assez rapide. Utilisez également
system.diagnostics.stopwatch code> pour mesurer le temps écoulé avec précision.1 °) En aucun cas. Le fichierize est de 19 Go et l'unité n'a que 8 Go de mémoire. En outre, la destination RAID0 peut prendre beaucoup plus de 100 Mo / SEC, le goulot d'étranglement ici est l'interface réseau Gigabit. 2 °) C'est un NAS très rapide :) Selon le repère, nous avons fait, il peut livrer entre 1200 et 1400 mbytes par seconde en lecture séquentielle.