Wie implementiere ich eine performante Dateikopie-Methode in C # von einer Netzwerkfreigabe?

8

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.

    
Altar 06.07.2010, 10:58
quelle

6 Antworten

0

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).

    
Jaroslav Jandek 06.07.2010, 11:16
quelle
5

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.

    
Adam Houldsworth 06.07.2010 11:01
quelle
4

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: Ссылка

    
Janick Bernet 06.07.2010 11:02
quelle
1

Es gibt die üblichen Verdächtigen für die Erhöhung der Geschwindigkeit über ein Netzwerk:

  • Mehrere Download-Threads haben
  • Ordnen Sie den Block auf der Festplatte vor, auf der sich die Datei befinden soll

Abgesehen davon sind Sie Ihren Hardwarebeschränkungen ausgeliefert.

    
codekaizen 06.07.2010 11:02
quelle
1

File.Copy() ruft einfach die CopyFile() API auf, Sie könnten p / invoke SHFileOperation() versuchen, was die Shell benutzt - oft scheint sie schneller zu sein.

    
Alex K. 06.07.2010 11:05
quelle
1

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. ...

  • Die Paketgröße des SMB-Protokolls
  • Wie viel Speicher möchten Sie für das Caching verwenden (was andere Prozesse verlangsamen kann)
  • Ob Sie Zuverlässigkeit für Geschwindigkeit opfern können
  • Ob Sie die wahrgenommene Geschwindigkeit oder die tatsächliche Zeit bis zum Ende erhöhen möchten
  • Wo und wie viel Sie auf mehreren möglichen Ebenen zwischenspeichern möchten
  • Ob Sie daran interessiert sind, verlässliches Feedback und geschätzte Zeit zu geben
Pontus Gagge 06.07.2010 11:15
quelle

Tags und Links