Reputation: 28693
Consider a simple program (posted below) that serializes the given number of objects using `ObjectOutputStream'. It calls the same function many times to serialize objects to a file. The first call takes longer than subsequent calls (the difference depends on the number of objects being serialized):
Serializing 10000 objects...
Time elapsed: 498ms
Time elapsed: 168ms
Time elapsed: 186ms
Serializing 100000 objects...
Time elapsed: 1815ms
Time elapsed: 1352ms
Time elapsed: 1338ms
Serializing 500000 objects...
Time elapsed: 8341ms
Time elapsed: 7247ms
Time elapsed: 7051ms
What is the reason for this difference? I tried to do the same thing without serialization, i.e. writing a byte array, and there is no such difference.
Update: the same thing happens if the program does not call the same method many times but serializes object in a for loop and then calls the method: the subsequent method call is faster:
"manual" serialization, time elapsed: 535
Time elapsed: 170ms
Time elapsed: 193ms
Time elapsed: 139ms
So JIT compilation cannot cause that difference.
Code:
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
public class SerializationTest {
static final int COUNT = 10000, TRIES = 3;
static class Simple implements Serializable {
String name;
int index;
Simple(String name, int index) {
this.name = name;
this.index = index;
}
}
public static void main(String[] args) throws IOException {
int count = COUNT;
if (args.length > 0) {
count = Integer.parseInt(args[0]);
}
List<Simple> objects = new ArrayList<Simple>();
for (int i = 0; i < count; i++) {
objects.add(new Simple("simple" + i, i));
}
String filename = args.length > 1 ? args[1] : "objects";
System.err.println("Serializing " + count + " objects...");
for(int i = 0; i < TRIES; i++) {
System.err.println("Time elapsed: " +
serializeOneByOne(objects, filename + i + ".bin", false) + "ms");
}
}
static long serializeOneByOne(List<?> objects, String filename, boolean buffered)
throws IOException {
OutputStream underlying = new FileOutputStream(filename);
if (buffered) {
underlying = new BufferedOutputStream(underlying);
}
ObjectOutputStream output = new ObjectOutputStream(underlying);
// take started after the output stream is open
// although it does not make a big difference
long started = System.currentTimeMillis();
try {
for (Object s : objects) {
output.writeObject(s);
}
} finally {
output.close();
}
long ended = System.currentTimeMillis();
return ended - started;
}
}
Upvotes: 2
Views: 2810
Reputation: 28693
The complete answer is that:
ObjectOutputStream has some internal static caches for several types of object is being serialized, (see ObjectStreamClass) so subsequent serializations of objects of the same type are faster than the first one.
JIT compilation may impact the performance if considering the compilation of ObjectOutputStream.writeObject
(and not the user-defined method as mentioned in another answers). Thanks to all who mentioned JIT compilation in their answers.
These also explains why there is no difference when writing a byte array instead of serializing objects: a) no static caches and b) FileOutputStream.write(byte [])
calls the native writeBytes
and almost no JIT compilation takes place.
Upvotes: 3
Reputation: 13066
JVM maintains a call count
for each method in your program.Each time you call the same method in a program its call count
increases. As soon as its call count
reaches to JIT compilation threshold
, this method is compiled
by JIT
. And next time this method is called , its execution is faster because now instead of interpreting the method interpreter is executing the native code . Hence the First call of same method takes more time than the subsequent calls.
Upvotes: 1
Reputation: 28727
In Java the JIT (Just in Time compiler) compiles when a method it called often (some recommedn calling it 10.000 times).
But java Serialisation is know to be slow and uses a huge amount of memory.
You can do better when you serialize yourself using a DataOutputStream.
java built in Serialisation if for fast demo projects, that works bug free right out of the box.
Upvotes: 1
Reputation: 4380
You're incurring in a lot of costs the first time you run it, JIT compilation, class loading, reflection, etc. This is normal, and most of the times no need to worry since the impact in a production app is negligible.
Upvotes: 0