0

I did a small benchmark test and found that ObjectOutputStream.writeObject is faster than ObjectOutputStream.write(byte[] bytes) but I can't seem to find a possible explanation as under the hood, writeObject will call ObjectOutputStream.write(byte[] bytes) indirectly

Test code

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

Output

write byte[] took: 15445 micros

writeObject took: 3111 micros

0

2 Answers 2

6

ObjectOutputStream.writeObject() conserves written objects. If you've already written that object, it only writes a handle to the same object, not the entire object.

Sign up to request clarification or add additional context in comments.

1 Comment

Indeed, you are correct. I replaced the code to have a new array everytime and the write byte array is now faster than writeObject. I totally forgot about the caching done by writeObject
1

I wrote a slight modification of your code:

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

Now the result is

write byte[] took: 51697 micros writeObject took: 57203 micros 

1 Comment

Thank you for your answer. Indeed I totally forgot about the caching mechanism in writeObject

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.