什么更快?
out.writeObject(someString)或out.writeUTF(someString)
答案 0 :(得分:8)
我希望人们从这个问题中学到两件事:Java序列化很慢 - 与它一起生活。微观标记比失败更糟糕。
微型商标往往会产生误导。有一些东西值得做一般的习惯用法(例如,在C中将strlen从循环中提升)。优化者习惯于打破微基准。获取您的应用程序并在实际负载下进行分析。如果一段代码导致程序变慢,请不要费心去优化它。 Microbenchmarks不会帮助您找到这些地方。
writeObject和writeUTF不会做同样的事情。 writeObject指示它要写入的对象类型。如果自上次重置以来已写入相同的对象(字符串),writeObject也会写入后引用。 writeUnshared更接近writeUTF。
因此,如果你继续写完全相同的长字符串writeObject应该赢,因为它只需要写一个后引用。减少序列化大小可能会降低文件/网络带宽或内存,这可能会带来更显着的性能提升。对于短字符串,只需写出数据就会更快。 writeUnshared应该提供几乎writeUTF性能,但保持通用性。
注意,在所有情况下,数据都写为UTF-8而不是UTF-16。如果你想要UTF-16 String.toCharArray
或类似的话。
答案 1 :(得分:4)
我写了一个测试用例,而writeObject更快。一个可能的原因是因为“请注意,将String作为基本数据或作为Object写入流中之间存在显着差异。将writeObject写入的String实例最初作为String写入流中。将来的writeObject()调用write将字符串引用到流中。“请参阅writeObject文档。
编辑:但是,writeUnshared仍然比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();
}
}
答案 2 :(得分:1)
我认为结果可能取决于someString
的内容。在我看来,发现writeUTF
性能发生变化并不是一个不合理的结果,因为使用了更高的unicode点,因此输出是多字节的。
请注意这是未经证实的,只是一个空想。
答案 3 :(得分:1)
你应该知道writeUTF只能处理长度为&lt;的字符串。 65535 ...
答案 4 :(得分:0)
不知道。
时间都是这些,它会比我们更快地告诉你。
for(int i=0; i<100000; i++) {
out.writeObject(someString);
}
for(int i=0; i<100000; i++) {
out.writeUTF(someString);
}
答案 5 :(得分:0)
使用DataOutputStrema.writeUTF()可以获得比ObjectOutputStream.writeUTF()更好的性能。