Puffergröße beim Dateikopieren

Kr0e

Gesperrter Benutzer
Hallo,

immer wieder hat mich verwundert, wieviel die Puffergröße beim Kopieren von Dateien von einer lokalen Festplatte auf eine andere lokale Festplatte ausmacht.

Ich meine jetzt nicht, dass es Vorteile bringt statt 128 byte Puffer einen 8192 byte Puffer zu benutzen. Ich meine, dass es (jenachdem welche Festplatten man hat!!) massive Unterschiede macht, ob man 32kb, 64kb oder vlt sogar 128kb benutzt.

Mein Problem ist, dass ich iwie das Gefühl hab, dass es da kein Patentrezept gibt, sondern es stark auf die Festplatte ankommt, die man benutzt.

Ich habe da ein paar Daten die bei einer recht gründlichen Testreihe entstanden sind:

Szenario:
900mb Datei auf Laufwerk C -> Kopieren auf Laufwerk D (Beides sind physikalische Laufwerke, beide SATA-II)
Die Laufwerke haben etwa eine Leistung um die 90-95 MB pro Sekunde. HD Tune hat diese Werte geliefert,
simples Kopieren mit Windows bestätigt dies.

Der Code:

Java:
        String file1 = "C:/test.ogg";
        String file2 = "D:/test.ogg";

        FileChannel input = new FileInputStream(file1).getChannel();
        FileChannel output = new FileOutputStream(file2).getChannel();

        ProgressFuture progress = new ProgressFuture(input.size());
        progress.addListener(new ProgressFutureListener() {

            public void operationUpdated(ProgressFuture future) throws Throwable {
                if (future.getLatestRateClock().getTimeValue(TimeUnit.Seconds) >= 1) {
                    System.out.println(future.getLatestRate(TimeUnit.Seconds));
                }
            }

            public void operationDone(ProgressFuture future) throws Throwable {
            }
        });

        ByteBuffer buffer = ByteBuffer.allocateDirect("Einer der Werte, die gleich beschrieben werden");

        while (!progress.isDone()) {
            int amount = input.read(buffer);
            buffer.flip();

            output.write(buffer);
            buffer.clear();

            progress.update(amount);
        }

1. Versuch (8192 Byte Puffer): zwischen 55 - 60 mb/s
2. Versuch (64*1024 Byte Puffer): zwischen 93-96 mb/s !!! (Sehr guter Wert!)
3. Versuch (128*1024 Byte Puffer): zwischen 20-70 mb/s (Schwankte stark, Durchschnitt war ebenfalls 55-60 wie beim 1. Versuch)

So, erst dachte ich "Gut, immer 64*1024" verwenden. Beim Testen auf einem anderen Computer, der sehr viel älter war und noch IDE Festplatten hatte, erreichte ich statt 35mb/s (Das war das Höchste, was dort HD Tune ermittelte) mit 64*1024 nur noch um die 18-20 mb/s. Dort waren 8192 Byte Puffer der Bringer.

Was habt ihr dabei für Erfahrungen ? Mir ist das Problem schon öfter mal aufgefallen, aber da ich nie riesige Dateien kopieren musste in meinen vorherigen Projekten, spielte das nur eine untergeordnete Rolle (mehr aus Interesse).

Gibt es eine Möglichkeit die ideale Puffergröße zu ermitteln ?

Meine Theorie dabei ist, dass Festplatten eine bestimmte Datenmenge effektiver lesen können, als andere Größen. Das z.B. beim Lesen von 128*1024 statt 64*1024 meine SATA Festplatten effezienter arbeiten. Aber ist nur eine Theorie.

Meine nächste Idee wäre mal, diese ganze Sache mal mit asynchronen FileChannels aus dem JDK7 zu probieren, diese können alle I/O-Operationen asynchron ausführen, bei Windows z.B. sind das die Completion Ports, die ein Event senden, wenn ein gewisser Vorgang fertig ist. Damit könnte man z.B. auf die 2. Festplatte Daten schreiben, während von der ersten Festplatte bereits Daten gelesen werden. Ich könnte mir vorstellen, dass man damit bestimmt bessere Geschwindigkeiten erzielen kann!

Also, was meint ihr zu diesem Thema ? Ist irgendwem das schonmal aufgefallen ? Liegt das vlt an schlecht fragmentierten Dateien ? Wobei ich mein System grad erst neu aufgesetzt hab und eigentlich sowas nicht zu erwarten ist...

Danke schonmal :)

Gruß,
Chris
 

moormaster

Top Contributor
Hast Du mal versucht, statt der read(ByteBuffer dst) - Methode
mal die read(ByteBuffer[] dsts, int offset, int length) - Methode zu benutzen?

ich könnte mir vorstellen, dass letztere unter Umständen bei hinreichend großem Puffer besser funktioniert, weil sie nicht zwingend den gesamten Puffer vollmacht bevor sie endet. Ist aber nur ne Vermutung :)
 

Wildcard

Top Contributor
Der Puffer arbeitet am schnellsten wenn der Puffer ein n-faches der Blockgröße des Dateisystems beträgt, leider lässt sich die nicht ohne weiteres herausfinden.
Große Dateien lassen sich wesentlich schneller per FileChannel kopieren. Das lohnt sich schon ab ein paar hundert Kilobyte
 

Kr0e

Gesperrter Benutzer
Hallo Zusammen,

den Effekt mit den Puffergrößen habe ich sowohl bei FileChannel als auch bei Streams gemerkt. Bei 64k sind beide sehr schnell, FileChannels etwas schneller als Streams (5-8mb/s). Aber bei z.B. 128k Blöcken sind sowohl Streams als auch Channels recht lahm.

Ich habe nun eine halb-Lösung:

Ich habe dieses asynchrone Lesen/Schreiben nun selbst implementiert (also ohne die JDK7 Klassen, da diese ja noch nicht Standard sind.) Quasi mit einem Threadpool... Nun erreiche mit 8k und höher die Maximalgeschwindigkeit der Festplatten. Ich benutze WIn7 übrigens. Beim Testen auf anderen Rechnern erziele ich gleiche Werte. Werde aber deim Release von JDK7 umsteigen auf die asynchronen Klassen, da dort OS-Threadpools im Spiel sind, die das ganze extremst beschleunigen können.

Danke und Gruß,

Chris
 

Kr0e

Gesperrter Benutzer
Vlt. lieg ich jetzt falsch, aber dort wird doch auch nur häppchenweise übertragen..
transferTo(offset, count, writeableChannel). Wenn ich bei offset null eingebe und für count channel.size() nehme,
bekomm ich erstmal ne OutOfMemory Exception. Diese Funktion mapped dnan nämlich ebenfalls die gesamte Datei in den Ram...
Was nciht sehr schlau ist. Also wahrscheinlich auch immer in kleinen Blöcken... Und dann hab ich den selben Effekt komischerweise...
bei Häppchen von 64k ist es am schnellsten .. Langsam hab ich das Gefühl, dass mit meiner JVM was nicht stimmt.. Weil es offensichtlich keiner nachvollziehen kann =(. Ich habe die JVM 64bit für Win7 64bit.
 

Wildcard

Top Contributor
Das passt schon. Mit channel.size() ist es am schnellsten, braucht bei sehr großen Dateien aber zuviel Heap. 64k Chunks ist sicherlich kein schlechter Standard Wert, denn den optimalen bekommt man leider nicht so einfach raus. Irgendwo ist in der API Doc AFAIR auch vermerkt das die Buffer Größe einen großen Einfluss auf die Performance nimmt und die ideale Größe Systemabhängig ist.
Mit einer nicht zu kleinen 2er Potenz macht man zumindest nichts falsch, insofern ist 64k wohl schon ok.
 

Kr0e

Gesperrter Benutzer
Werd ich mir merken, danke soweit erstmal :) Man kann ja im Programm die Möglichkeit geben, diese Puffergröße einzustellen, sofern nicht zufriedenstellende Transferraten erreicht werden, bzw. nicht erreicht werden.

Gruß,

Chris
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
E Zip-File entpacken: unterschiedlicher Zeitaufwand bei unterschiedlicher Puffergröße Allgemeine Java-Themen 2
Zrebna OutOfMemory-Error beim Build in der CI-Pipeline Allgemeine Java-Themen 5
berserkerdq2 Weiß jemand wie ich im Scenebuilder das Fenster so darstellen kann, dass beim Vollbildmodus die Objekte so angezeigt werden? Allgemeine Java-Themen 1
C Probleme beim Erstellen eines runnable-jar files Allgemeine Java-Themen 1
B Mysteriöse Ergebnisse beim Baccarat Programm? Allgemeine Java-Themen 13
8u3631984 Problem beim Mocken von Record Klassen Allgemeine Java-Themen 4
A Zweite Service Klasse beim Kompilieren Allgemeine Java-Themen 6
B Java Reflection Probleme beim wehcselseitigen Referenzieren zweier Klassen/Objekte Allgemeine Java-Themen 14
B Stringmanipulationen beim Dateinamen Allgemeine Java-Themen 8
B Woher kommen die Bildschirmkoordinaten beim java Robot? Allgemeine Java-Themen 14
Alex_99 Programm stürzt beim Aufruf der Funktion ab? Text ausgeben Allgemeine Java-Themen 45
J Mein Frame friert ein beim Uploaden Allgemeine Java-Themen 4
P Selenium Scriipt zeigt Fehler beim Import Allgemeine Java-Themen 3
A Hilfe beim Verständnis Allgemeine Java-Themen 16
stormyark Problem beim Klassen erstellen Allgemeine Java-Themen 1
K Verbesserung der Laufzeit beim Sortieren von Einwohnern nach ihrem Geburtsjahr Allgemeine Java-Themen 0
B Compiler-Fehler Probleme beim Kompilieren mit Jsoup Allgemeine Java-Themen 8
G javamail Problem beim Empfangen von Nachrichten Allgemeine Java-Themen 3
yakazuqi Fehler beim Laden. JDA (Java Discord API) Allgemeine Java-Themen 1
T Problem beim Umwandeln in eine Jar-Datei Allgemeine Java-Themen 3
W Suche Ursache für NPE - woher kommt sie? (Hilfe beim Debugging) Allgemeine Java-Themen 19
U Fehler beim Compillieren Allgemeine Java-Themen 13
B neuroph hält beim XOR lernen nicht an Allgemeine Java-Themen 13
bueseb84 Fehler beim Import von Maven Dependencies aus lokalem artifactory Allgemeine Java-Themen 2
J Jasper Report - seltame Meldung beim compilieren Allgemeine Java-Themen 3
J Linux .jar beim Start automatisch ausführen Allgemeine Java-Themen 6
T String-Manipulation beim Ablauf in Eclipse und als JAR-File Allgemeine Java-Themen 8
V Threads Probleme beim Aufrufen von Methoden einer anderen Klasse (Threads) Allgemeine Java-Themen 14
M Gibt es eine API die den aktuellen Wert eines Indikators beim Trading zurückgibt? Allgemeine Java-Themen 7
A Fehler beim Öffnen eines Projekts Allgemeine Java-Themen 6
L Compiler-Fehler Generics beim Anhängen von Predicates Allgemeine Java-Themen 1
J WARNING: An illegal reflective access operation has occurred, beim Compilieren von JasperReports, was bedeutet das ? Allgemeine Java-Themen 23
J Problem beim Umstellen auf Java jdk 13 Allgemeine Java-Themen 3
A Problem beim öffnen von Java-Installern Allgemeine Java-Themen 1
J Problem beim Generischen Klassen und Interfaces Allgemeine Java-Themen 2
C Fehler beim Debuggen von Listen Allgemeine Java-Themen 4
L File beim Kopieren in einen anderen Ordner umbenennen Allgemeine Java-Themen 6
B Input/Output Probleme beim Ausführen von Shell-Befehlen mit Java Allgemeine Java-Themen 28
J Probleme beim einbinden von Zip4j library Allgemeine Java-Themen 6
T Compiler-Fehler NoClassDefFoundError beim Laden einer Class Allgemeine Java-Themen 11
S Seitenausrichtung beim Drucken Allgemeine Java-Themen 1
RalleYTN Brauche Hilfe beim Run-Length-Decoding Allgemeine Java-Themen 9
R Optimierung beim Vergleichen von 2 Bildern Allgemeine Java-Themen 23
F SQLite mit Java / Probleme beim INSERT Befehl Allgemeine Java-Themen 4
I Fehler beim Ant-Package erstellen mit Java 9 Allgemeine Java-Themen 1
S Eclipse Probleme beim Implementieren / Ausführen von jUnit 5-Test Suites Allgemeine Java-Themen 14
M Beim Öffnen Dialog Directory und Filetype definieren Allgemeine Java-Themen 2
G Problem beim GUI Allgemeine Java-Themen 9
A Probleme beim Verstehen einer Aufgabenstellung Allgemeine Java-Themen 11
A OOP Problem beim Berechnen der größten Fläche eines Ringes Allgemeine Java-Themen 19
F Problem beim Einlesen einer Textdatei Allgemeine Java-Themen 12
J Konstruktor in JSP beim Kompilieren nicht gefunden Allgemeine Java-Themen 3
perlenfischer1984 Probleme beim Mocken Allgemeine Java-Themen 6
A Fehler beim Aktualisieren JTable Allgemeine Java-Themen 1
D Pivot-Wahl beim QuickSort steigert die Effizienz, eine Lüge??? Allgemeine Java-Themen 17
J-Gallus Erste Schritte Wahrscheinlich Anfänger Fehler beim rechnen. Falsches Ergebnis. Allgemeine Java-Themen 9
U Swing Hilfe beim Quellcode für ein Codierungs-/Decodierungsprogramm Allgemeine Java-Themen 9
Fischkralle Beim Clean Coden an den Schnittstellen geschnitten. Allgemeine Java-Themen 10
H Beim Konstruktor "this" Allgemeine Java-Themen 4
I Problem beim Aufrufen, von Objektmethoden/ -variablen Allgemeine Java-Themen 6
J Interpreter-Fehler Fehler beim Verschlüsseln Invalid AES key length Allgemeine Java-Themen 1
R probleme beim starten von jar unter linux Allgemeine Java-Themen 2
Thallius Swing Merkwürdiges Verhalten beim Panel Tausch Allgemeine Java-Themen 3
Tacofan Sound beim öffnen der GUI Allgemeine Java-Themen 8
Z NullPointerException beim Schreiben einer ArrayList in eine Datei Allgemeine Java-Themen 6
B Endlosschleife beim Verteilen von Objekten Allgemeine Java-Themen 4
V JavaFX Fehler beim Starten einer Jar Allgemeine Java-Themen 7
B Fortschritt beim Schreiben einer Datei ausgeben lassen Allgemeine Java-Themen 7
J JDK installieren Das Jdk funtioniert beim Editor nicht. Allgemeine Java-Themen 3
R Verdrückt beim Sicherheitshinweis Allgemeine Java-Themen 2
M Probleme beim rechnen, bei Zahlen mit führenden Nullen. Allgemeine Java-Themen 7
javampir Input/Output Effizienz beim binären Lesen einer Datei Allgemeine Java-Themen 6
javampir Seltsame Lücken beim Abspielen von Sound Allgemeine Java-Themen 2
RalleYTN JAnsi Warum bleiben die Hintergrundfarben beim Reseten der Konsole? Allgemeine Java-Themen 0
T BufferedImage verändert sich beim Einlsesen Allgemeine Java-Themen 1
E JCuda-0.6.5 Probleme beim ausführen der Datei Allgemeine Java-Themen 0
S Verständnisproblem beim Mocking Allgemeine Java-Themen 8
W JNDI - LDAP - Probleme beim editieren von Usern Allgemeine Java-Themen 0
Athena Programm funktioniert nur beim Debugging korrekt, sonst nicht. Allgemeine Java-Themen 1
N Zahlensysteme umrechnen; Probleme beim Umwandeln Allgemeine Java-Themen 4
K Fehler beim erstellen von .jar Datei Allgemeine Java-Themen 3
M Eclipse Fehler beim Installieren des Plugins "Jigloo" Allgemeine Java-Themen 12
A Eclipse - Fehler beim "RUN" - "Unable to Launch - The selection cannot be launched" Allgemeine Java-Themen 6
G StackoverflowError beim laden einer FXMML Datei Allgemeine Java-Themen 1
L Methoden Methode gibt mir beim verschlüsseln mit RSA 0 bytes aus ? Allgemeine Java-Themen 1
D Selenium WebDriver HtmlUnitDriver Problem beim Automatisieren Allgemeine Java-Themen 1
A Probleme beim auslesen von Quelltext (HTML) Allgemeine Java-Themen 5
D Input/Output Zeilen werden "ignoriert" beim Einlesen aus einer Textdatei Allgemeine Java-Themen 3
L Suchvorschläge beim eingeben einzelner Buchstaben Allgemeine Java-Themen 3
B Compiler-Fehler NullPointerException beim Auslesen von .lang-Datei Allgemeine Java-Themen 3
U Eclipse Java Programm beschädigt .tar.gz dateien beim Entpacken Allgemeine Java-Themen 7
B Fehler beim Auslesen von Einstellungen. Zwei ähnliche Blöcke, nur eins geht. Allgemeine Java-Themen 5
P Auf die Anzahl der Joins achten beim WS design Allgemeine Java-Themen 1
reibi Classpath Classpath Variable beim Tomcat Allgemeine Java-Themen 2
H JUnit Fehler beim Compilieren - erledigt Allgemeine Java-Themen 0
J Fehler beim parsens eine Datums Allgemeine Java-Themen 3
A Java - Beim Abspeichern Redundanzen vermeiden! Allgemeine Java-Themen 6
L einfache Verzinsung mit for-Schleife & Ausschluss von Werten beim Einlesen Allgemeine Java-Themen 5
C Bufferoverflow beim eigenen simpeln Programm Allgemeine Java-Themen 4
MiMa Umlaute beim Einlesen von Dateinamen Allgemeine Java-Themen 12

Ähnliche Java Themen

Neue Themen


Oben