In a response to a recent JavaLobby thread, Tom Hawtin looks at optimization of serialization and decides that you shouldn't do it.
The JavaLobby post describes a few different options for optimization and found that by using the Externalizable interface, instead of Serializable, yields significant performance gains (up to 55% in one version of the JDK). Hatwin noted some flaws in the microbenchmark, most significantly:
Serializable objects that implement Externalizable do not have fields included in their class descriptors. Not a lot of people know that. The descriptions are used if there is no writeObject/readObject method and for defaultReadObject and readFields. So, for fairness, the fields for the writeObject/readObject version should be marked as transient.
After running his updated microbenchmark he finds four conclusions:
- Don't use Externalizable
- Do reuse streams
- Implementing writeObject and readObject by hand can improve performance
- JVMs get better at serialization with each release
In a follow up to his benchmark, Hatwin finds a small optimization that is valuable. He notes that calling ObjectStreamClass.lookup on all classes that you are going to serialize, and assigning the results to static fields, will provide a boost. The boost comes from the fact that the soft reference cache used by serialization will never miss if you hold on to a reference. He has not yet updated his benchmarks to show the impact on it.
Community comments
JBoss Serialization
by Sacha Labourey,
you need multi-threaded microbench
by Bill Burke,
Re: you need multi-threaded microbench
by Thomas Hawtin,
JBoss Serialization
by Sacha Labourey,
Your message is awaiting moderation. Thank you for participating in the discussion.
You might want to check "JBoss Serialization" as well (led by Clebert Suconic):
labs.jboss.com/portal/serialization/
From the project page:
you need multi-threaded microbench
by Bill Burke,
Your message is awaiting moderation. Thank you for participating in the discussion.
If you run a multi-threaded microbench you'll find that the SoftReferenceCache mentioned above becomes a point of contention because it is accessed in a synchronized block. Performance starts to degrade after like 50-100+ threads because of the contention. Replacing this cache with a ConcurrentHashMap (i used the oswego one when I did my benchmarks) removes this contention and give you better scalability.
Bill
Re: you need multi-threaded microbench
by Thomas Hawtin,
Your message is awaiting moderation. Thank you for participating in the discussion.
Recent 1.5.0 updates (and 1.6.0) have ditched ye olde SoftCache for a new concurrent-friendly cache. I'm not going to suggest that java.io has respectable performance, but it's an improvement.