为什么ObjectOutputStream.writeObject在写入字节数组时比写入字节更快?
问题描述:
我做了一个小的基准测试,发现ObjectOutputStream.writeObject
快于ObjectOutputStream.write(byte[] bytes)
,但我似乎无法找到一个可能的解释是引擎盖下,writeObject
将调用ObjectOutputStream.write(byte[] bytes)
间接为什么ObjectOutputStream.writeObject在写入字节数组时比写入字节更快?
测试代码
public static void main(String[] args) throws Exception {
byte[] bytes = new byte[10000];
for (int i = 0; i < 10000; ++i) {
bytes[i] = (byte) (i % 256);
}
ByteArrayOutputStream out2 = new ByteArrayOutputStream();
try(ObjectOutputStream ostream2 = new ObjectOutputStream(out2)) {
for (int i = 0; i < 10000; ++i) {
ostream2.writeInt(bytes.length);
ostream2.write(bytes, 0, bytes.length);
}
out2.reset();
long start = System.nanoTime();
for (int i = 0; i < 10000; ++i) {
ostream2.writeInt(bytes.length);
ostream2.write(bytes, 0, bytes.length);
}
long end = System.nanoTime();
System.out.println("write byte[] took: " + ((end - start)/1000) + " micros");
}
ByteArrayOutputStream out = new ByteArrayOutputStream();
try(ObjectOutputStream ostream = new ObjectOutputStream(out)) {
for (int i = 0; i < 10000; ++i) {
ostream.writeObject(bytes);
}
out.reset();
long start = System.nanoTime();
for (int i = 0; i < 10000; ++i) {
ostream.writeObject(bytes);
}
long end = System.nanoTime();
System.out.println("writeObject took: " + ((end - start)/1000) + " micros");
}
}
输出
写字节[]了:15445万分之一
的writeObject了:3111万分之一
答
ObjectOutputStream.writeObject()
节省写对象。如果你已经写过那个对象,它只会写一个句柄给同一个对象,而不是整个对象。
答
我写你的代码稍加修改:
public class Test {
public static final int REPS = 10000;
public static void main(String argv[]) throws IOException {
ByteArrayOutputStream out2 = new ByteArrayOutputStream();
try (ObjectOutputStream ostream2 = new ObjectOutputStream(out2)) {
writeBytes(ostream2);
out2.reset();
long start = System.nanoTime();
writeBytes(ostream2);
long end = System.nanoTime();
System.out.println("write byte[] took: " + ((end - start)/1000) + " micros");
}
ByteArrayOutputStream out = new ByteArrayOutputStream();
try (ObjectOutputStream ostream = new ObjectOutputStream(out)) {
writeObject(ostream);
out.reset();
long start = System.nanoTime();
writeObject(ostream);
long end = System.nanoTime();
System.out.println("writeObject took: " + ((end - start)/1000) + " micros");
}
}
private static void writeObject(ObjectOutputStream ostream) throws IOException {
for (int i = 0; i < REPS; ++i) {
final byte[] bytes = bytes();
ostream.writeObject(bytes);
}
}
private static void writeBytes(ObjectOutputStream ostream2) throws IOException {
for (int i = 0; i < REPS; ++i) {
final byte[] bytes = bytes();
ostream2.writeInt(bytes.length);
ostream2.write(bytes, 0, bytes.length);
}
}
static byte[] bytes() {
byte[] bytes = new byte[REPS];
for (int i = 0; i < REPS; ++i) {
bytes[i] = (byte) i;
}
return bytes;
}
}
现在的结果是
write byte[] took: 51697 micros
writeObject took: 57203 micros
+0
谢谢你的回答。的确,我完全忘记了writeObject中的缓存机制 –
事实上,你是正确的。我将代码替换为每次都有一个新数组,写入字节数组现在比writeObject快。我完全忘记了writeObject所做的缓存 –