Ich versuche, eine Dateikopie-Methode zu implementieren, die die Leistung einer Kopie mit dem Windows-Explorer übereinstimmen kann.
Zum Beispiel eine Kopie (mit dem Windows Explorer) von unserer NAS zu meinem Computer, führt über 100mb / sec.
Meine aktuelle Implementierung macht die gleiche Kopie mit etwa 55 MB / s, was bereits besser ist als die System.IO.File.Copy (), die mit 29 MB / s arbeitet.
%Vor%Irgendeine Idee, wie Sie die Leistung verbessern können?
BEARBEITEN:
Die Datei wird von einem Linux-basierten NAS mit einer 10-Gigabit-Ethernet-Schnittstelle mit 60 Laufwerken gelesen (mach dir keine Sorgen über seine Leistung, es funktioniert sehr gut) und auf einen lokalen Raid0 geschrieben, der Daten schreiben kann etwa 140 MB / s.
Der Engpass ist die Gigabit-Netzwerkschnittstelle des Ziels, die ich mit meinem aktuellen Code nicht erreichen kann.
Außerdem wird durch das Entfernen des Schreibvorgangs das Lesen nicht schneller, so dass ich diese Lesegrenze von 55 MB / s nicht überschreiten kann.
EDIT 2:
Das Geschwindigkeitsproblem hängt mit der Tatsache zusammen, dass die Quelldatei auf einer Netzwerkfreigabe gespeichert ist. Nur das Lesen von meinem lokalen Laufwerk mit meinem Code bietet mir eine Geschwindigkeit von 112 MB / s.
EDIT 3:
Samba scheint nicht das Problem zu sein. Ich ersetzte die cifs-Freigabe (Samba) durch eine nfs-Freigabe auf meinem Linux-Nas und bekam schlechtere Ergebnisse als mit Samba auf meinem win7-Client.
Mit nfs hatten meine Kopiermethode und der Windows Explorer die gleiche Leistung, etwa 42 MB / Sek.
Ich habe keine Ideen mehr ...
EDIT 4:
Nur um sicher zu sein, dass Windows das Problem war, habe ich eine Debian-Lenny installiert, habe meine Nas-Nfs gemountet und habe 79MB / Sek. mit dem gleichen Code unter Mono bekommen.
Wahrscheinlich wäre die einzige schnellere Option die Verwendung von unbuffered IO
: ReadFile-Funktion , < a href="http://msdn.microsoft.com/en-us/library/aa363858.aspx"> CreateFile-Funktion , WriteFile-Funktion mit dem FILE_FLAG_NO_BUFFERING
-Flag mit 2-6 MB Puffer.
Auch auf diese Weise müssten Sie die Puffergröße an die Dateisystemgröße anpassen usw.
Es wäre erheblich schneller - vor allem in Windows XP.
übrigens. Ich habe ~ 400 MB Bandbreite auf einem gestreiften RAID 0-Array auf diese Weise erreicht (mit 4 MB Puffer).
Versuchen Sie, die Puffergröße so zu ändern, dass sie der Sektorgröße auf der Festplatte entspricht - wahrscheinlich 4 KB. Verwenden Sie auch die System.Diagnostics.Stopwatch-Klasse für das Timing.
Ich würde auch nicht die asynchronen Methoden in einer engen Schleife verwenden - es wird etwas Overhead weggehen und einen Thread aus dem Pool zuweisen, um die Arbeit zu erledigen.
Verwenden Sie auch die using
-Anweisung erneut, um die Entsorgung Ihrer Streams zu verwalten. Beachten Sie jedoch, dass dies Ihr Timing verfälscht, da Sie die Objekte nach dem Stoppen des Timers gerade entsorgen.
Haben Sie kleinere Puffergrößen versucht? Eine Puffergröße von 1 MB ist schrecklich groß und normalerweise bieten Puffergrößen von 4-64 KB die beste Leistung.
Dies hängt möglicherweise auch mit Ihrer Frage zusammen: Wie schreibe ich superschnellen Datei-Streaming-Code in C #?
Und vielleicht können Sie die Leistung verbessern, indem Sie Speicherkarten verwenden: Ссылка
Es gibt die üblichen Verdächtigen für die Erhöhung der Geschwindigkeit über ein Netzwerk:
Abgesehen davon sind Sie Ihren Hardwarebeschränkungen ausgeliefert.
Für ein tieferes Verständnis der Designoptionen und der Kompromisse beim Kopieren von Dateien mit und ohne Netzwerkfreigaben empfehle ich Ihnen, sich Mark Russinovich's Blogpost vor ein paar Jahren. Es gibt viel mehr Falten als nur die Festplattensektorgrößen, z. B. ...
Tags und Links c# windows performance copy