Datei kopieren: out << in.rdbuf() saulangsam.
-
Hallo zusammen,
ich suche nach dem schnellsten Weg, um plattformunabhängig eine Datei in eine andere zu kopieren.
Überall wird für eine Dateikopie von ifstream IN in ofstream OUT die Vorgehensweise
OUT << IN.rdbuf() empfohlen.Dies dauert in meinem Fall (39 MB große Datei) 15-17 Sekunden.
Habe dann scherzeshalber mal char c = in.get(); out.put(c) ausprobiert. Diese Vorgehensweise dauert 12-13 Sekunden.
Kann mir jemand sagen, warum die als "Standard" erwähnte erste Variante so viel langsam als die gefühlsmäßig schlechtere Variante mit byteweisem Kopieren ist?
Ich meine, TotalCommander, Linux-cp und Windows-copy erledigen die Kopieraufgabe in maximal 3 Sekunden.
Gruss
Sid
-
Nimm Funktionen des Betriebsystems, das ist am schnellsten.
-
Die Variante empfiehlt sich allerhöchstens für sehr kleine Dateien. Optimal ist die Kopiergeschwindigkeit wenn die Daten in Blöcken kopiert werden, die der Blockgröße im Kernel entspricht. Üblicherweise einigt man sich aber hier auf 4 bis 8 KB Blöcke.
Die rdbuf-Variante liest zuerst ALLE Daten in den Speicher, und schreibt dann alle hintereinander in die Ausgabedatei. D.h. es muss viel Speicher (nach)alloziiert werden, und wenn die Dateigröße entsprechend ist muss der Kernel sogar swappen.
Die blockweise Variante benötigt keine Allokationen, wenn mit einem festen Transferpuffer gearbeitet wird, und wenn unterschiedliche Geräte involviert sind kann der Kernel sogar parallel lesen und schreiben lassen, was den Vorgang natürlich nochmal beschleunigt.
Die zeichenweise Variante kann zwar im besten Fall auch parallel arbeiten, springt aber zuviel hin und her, um da einen großen Nutzen draus zu ziehen und die Aufgabe effizient erledigen zu können.
EDIT: Beispiel als Pseudocode
byte buffer[8K]; int size; while ((size = read(infile, buffer, 8K)) > 0) { write(outfile, buffer, size); }Annahmen: read und write sind blockierend, liefern bzw nehmen also so viele Daten wie möglich und nicht wie vorhanden.
-
LordJaxom schrieb:
Die rdbuf-Variante liest zuerst ALLE Daten in den Speicher, und schreibt dann alle hintereinander in die Ausgabedatei.
Das stimmt zumindest für die Dinkumware-STL nicht. Ich kann es mir auch nicht vorstellen, dass es in anderen STL-Implementierungen so gemacht ist, da ein Stream (File) mehr Zeichen enthalten darf als ein Allokator Memory heranschaffen kann.
Gruß
Werner
-
Sid2K6 schrieb:
ich suche nach dem schnellsten Weg, um plattformunabhängig eine Datei in eine andere zu kopieren.
http://www.boost.org/libs/filesystem/doc/index.htm
Sehr gute lib.
hat nur den nachgeschmak, das man nicht mit chmod arbeiten kann, dann muss
man mit#ifndef __WIN__ (oder so) #include <sys/types.h> #include <sys/stat.h> #endif /... #ifndef __WIN__ (oder so) chmod(path, mode); #endifarbeiten
Viel spass ^^
Gg