Was ist schneller?
out.writeObject (someString) oder out.writeUTF (someString)Java writeObject Vs. writeUTF
Antwort
Ich schrieb einen Testfall, und writeObject ist schneller. Ein möglicher Grund ist folgender: "Beachten Sie, dass ein wesentlicher Unterschied zwischen dem Schreiben eines Strings in den Stream als primitive Daten oder als Objekt besteht. Eine von writeObject geschriebene String-Instanz wird zunächst als String in den Stream geschrieben. Future writeObject() ruft write auf Verweise auf die Zeichenfolge in den Stream. " Siehe die writeObject-Dokumentation.
EDIT: Allerdings ist writeUnshared immer noch schneller als writeUTF,
100000 runs of writeObject: 464
100000 runs of writeUnshared: 5082
100000 runs of writeUTF: 7541
import java.io.*;
public class WriteString
{
private static int RUNS = 100000;
private static int STR_MULTIPLIER = 100;
public static void main(String[] a) throws Throwable
{
StringBuilder builder = new StringBuilder(26 * STR_MULTIPLIER);
for(int i = 0; i < STR_MULTIPLIER; i++)
{
builder.append("abcdefghijklmnopqrstuvwxyz");
}
String str = builder.toString();
File f = new File("oos");
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(f));
long startObject = System.currentTimeMillis();
for(int i = 0; i < RUNS; i++)
{
oos.writeObject(str);
oos.flush();
}
long endObject = System.currentTimeMillis();
System.out.println(RUNS + " runs of writeObject: " + (endObject - startObject));
long startUnshared = System.currentTimeMillis();
for(int i = 0; i < RUNS; i++)
{
oos.writeUnshared(str);
oos.flush();
}
long endUnshared = System.currentTimeMillis();
System.out.println(RUNS + " runs of writeUnshared: " + (endUnshared - startUnshared));
long startUTF = System.currentTimeMillis();
for(int i = 0; i < RUNS; i++)
{
oos.writeUTF(str);
oos.flush();
}
long endUTF = System.currentTimeMillis();
System.out.println(RUNS + " runs of writeUTF: " + (endUTF - startUTF));
oos.close();
f.delete();
}
}
Das ist insofern überraschend, als writeObject intern prüft, ob das Objekt ein String ist, und writeUTF aufruft. –
@AndrewFinnell, ja, ich bestätigte die Ergebnisse, aber ich bin mir nicht sicher warum. Sie haben Recht, dass es keine Unterscheidung nach UTF-16 v. UTF-8 gibt (writeString ruft writeUTF auf, das ist modifiziertes UTF-8). Es könnte zu einem Testartefakt werden. Ich bin mir besonders nicht sicher, warum writeUnshared schneller ist, wenn es mehr tut und doppelte Kopien schreibt. –
Ist das nicht ein gutes Beispiel dafür, wie man einen Mikro-Benchmark NICHT macht? – nilskp
Keine Ahnung.
Zeit beide von diesen und es wird Ihnen schneller sagen, als wir können.
for(int i=0; i<100000; i++) {
out.writeObject(someString);
}
for(int i=0; i<100000; i++) {
out.writeUTF(someString);
}
Dann wechseln Sie die Reihenfolge der Schleifen und staunen Sie, wie wenig Ihnen das sagt. – nilskp
Ich würde davon ausgehen, dass das Ergebnis auf die Inhalte der someString
abhängen. Es fällt mir ein, dass es kein unangemessenes Ergebnis wäre, wenn sich die Leistung ändert, da die höheren Unicode-Punkte verwendet werden, so dass die Ausgabe Multi-Byte ist.
Bitte beachten Sie, dies ist unbewiesen und ist nur ein leerer Gedanke.
Es gibt zwei Dinge, die ich Menschen von dieser quesiton lernen wollen: Java Serialisierung ist langsam - damit leben. Microbenchmarks sind schlimmer als Fehler.
Mikropräparationen sind in der Regel irreführend. Es gibt einige Dinge, die es wert sind, als allgemeines Idiom ausgeführt zu werden (z. B. das Herausziehen der Schleife in C). Optimierer haben die Angewohnheit, Microbenchmarks zu brechen. Nimm deine Anwendung und profiliere sie unter Reallast. Wenn ein Programmcode Ihr Programm verlangsamt, optimieren Sie es nicht. Microbenchmarks werden Ihnen nicht helfen, diese Orte zu finden.
writeObject und writeUTF machen nicht dasselbe. writeObject gibt an, welche Art von Objekt es schreiben wird. WriteObject schreibt auch eine Zurück-Referenz, wenn das gleiche Objekt (String) seit dem letzten Zurücksetzen geschrieben wurde. writeUnshared ist näher an writeUTF.
Also, wenn Sie weiterhin genau die gleiche lange String writeObject schreiben sollte gewinnen, weil es nur eine Rückverweis schreiben muss. Die Reduzierung der serialisierten Größe kann die Datei-/Netzwerkbandbreite oder nur den Arbeitsspeicher verringern, was zu größeren Leistungsverbesserungen führen kann. Bei kurzen Strings ist das Schreiben der Daten schneller. writeUnshared sollte fast writeUTF-Leistung liefern, aber die Allgemeinheit beibehalten.
Hinweis: In allen Fällen werden Daten als UTF-8 und nicht als UTF-16 geschrieben. Wenn Sie möchten UTF-16 String.toCharArray
oder ähnliches tun.
Mit DataOutputStrema.writeUTF() erhalten Sie eine bessere Leistung als mit ObjectOutputStream.writeUTF().
Sie sollten sich bewusst sein, dass writeUTF nur Strings mit einer Länge < 65535 ...
- 1. Serialisierung - readObject writeObject überschreibt
- 2. AS3 ByteArray writeObject() XMLList ist null
- 3. Was ist der Unterschied zwischen writeUTF und writeChars?
- 4. Wie kann ich C++ verwenden, um eine Datei zu lesen, die mit Java (writeObject) gespeichert wurde
- 5. Warum wir Externalizable haben, wenn wir writeObject und readObject in Java überschreiben können
- 6. Android-java vs PC-Java
- 7. UTC vs. GMT - Java vs. .Net
- 8. Liste vs Warteschlange vs Sammlung in Java
- 9. + = vs = + in Java
- 10. Klassenmitglieder - Java vs. Python
- 11. Java: Ganzzahl gleich vs. ==
- 12. Java: ArrayBlockingQueue vs. LinkedBlockingQueue
- 13. Hausgemachte vs Java-Serialisierung
- 14. Java CachedThreadPool vs FixedThreadPool
- 15. Java Vererbung vs Polymorphismus
- 16. Java Swing: repaint() vs
- 17. Java Enumeration vs Iterator
- 18. Java überladen vs überschreiben
- 19. Double vs Float - Java
- 20. .class vs .java
- 21. Java Regex "[.]" Vs "."
- 22. Java Thread.stop() vs Thread.interrupt()
- 23. Java Logging vs Log4J
- 24. Java Vererbung vs Initialisierung
- 25. Klasse vs Paket vs Modul vs Komponente vs Container vs Service vs Plattform in Java Welt
- 26. Java 32bit Xmx vs Java 64bit Xmx
- 27. Java 8 Leistung VS. Java 7
- 28. Java hartcodierte Schalter vs hashmap
- 29. float vs double (in Java)
- 30. Java Swing revalidate() vs repaint()
Sicher handhaben können Sie dies selbst heraus durch Profilierung haben könnte. –
Erwähnenswert: 'writeUTF' behandelt _not_ nicht mit' null'. – nilskp