为什么写字节数组时 ObjectOutputStream.writeObject 比写字节快?

Why is ObjectOutputStream.writeObject faster than write bytes when writing a byte array?

我做了一个小的基准测试,发现 ObjectOutputStream.writeObjectObjectOutputStream.write(byte[] bytes) 快,但我似乎找不到可能的解释,因为在幕后,writeObject 会调用ObjectOutputStream.write(byte[] bytes) 间接

测试代码

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");
    }
}

输出

write byte[] took: 15445 micros

writeObject took: 3111 micros

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