Use sun.misc.Unsafe in FieldSerializer (gives 10x performance boost)

165 views
Skip to first unread message

Kai

unread,
Dec 30, 2010, 7:14:09 AM12/30/10
to kryo-users
Hi,

I was using the kryo serialization library for some time now and used
it to serialize/deserialize objects with the FieldSerializer.
Profiling showed that most of the time is spent in the reflection
methods Field.get and Field.set.

For the Oracle JVM, there is the class sun.misc.Unsafe, which can be
used as drop-in replacement for reflection.
Using Unsafe instead of Field.get and Field.set, the FieldSerializer
became about 10x faster.

Kryo would definitely benefit from that Unsafe class (where available)
in terms of performance. But care must be taken, because Unsafe does
not check field assignability. When a value assigned to a field is not
compatible to that field, the JVM crashes with a thread dump when that
assigned field is being accessed afterwards.

Just wanted to mention that Unsafe could be used to increase
performance of the FieldSerializer.

Regards,
Kai

Ronen

unread,
Dec 31, 2010, 4:37:52 AM12/31/10
to kryo-users
Are your fields public? if they are then Kryo uses ASM generated code
which is much faster then reflection:

"Most classes will use FieldSerializer. This is convenient because it
does not require classes to implement an interface to be serialized.
FieldSerializer does direct assignment to the object's fields. If the
fields are public, bytecode generation is used for maximum speed. For
non-public fields, cached reflection is used, which is still quite
fast. FieldSerializer can handle any acyclic object graph."

Kai

unread,
Dec 31, 2010, 7:12:36 AM12/31/10
to kryo-users
> Are your fields public?
Most of them are private, and in my optinion, following the principle
of "information hiding" and "encapsulation", a field should never be
public. Also, the classes I want to serialize, I do not have control
over.

> if they are then Kryo uses ASM generated code which is much faster then reflection:
Thanks for the info. Yes, I tried that, and it is indeed much faster
than reflection but as mentioned in another post here in this group
[http://groups.google.com/group/kryo-users/browse_thread/thread/
ebad155b1c5c0a27/ec3d66ea0d9bd2a2?
lnk=gst&q=Verification#ec3d66ea0d9bd2a2], when profiling the app the
ASM generated code results in a VerificationError being thrown at
class load time, which is unacceptable for production code.

I just wanted to mention that using com.sun.Unsafe (for private
fields; or any other fields) for me is preferrable to both ASM (gives
VerificationError) and Reflection (is slow).

Nate

unread,
Jan 10, 2011, 7:30:42 PM1/10/11
to kryo-...@googlegroups.com
On Fri, Dec 31, 2010 at 4:12 AM, Kai <kbur...@googlemail.com> wrote:
Thanks for the info. Yes, I tried that, and it is indeed much faster
than reflection but as mentioned in another post here in this group
[http://groups.google.com/group/kryo-users/browse_thread/thread/
ebad155b1c5c0a27/ec3d66ea0d9bd2a2
?
lnk=gst&q=Verification#ec3d66ea0d9bd2a2], when profiling the app the
ASM generated code results in a VerificationError being thrown at
class load time, which is unacceptable for production code.

Whatever error this user had (they never followed up) is likely to either be fixed already, or a problem between the user's screen and chair. :)
 
I just wanted to mention that using com.sun.Unsafe (for private
fields; or any other fields) for me is preferrable to both ASM (gives
VerificationError) and Reflection (is slow).

10x is a nice improvement. It sounds about the same difference as ASM versus reflection, see chart here:
http://code.google.com/p/reflectasm/
The difference being that Unsafe can break the JVM's rules while ReflectASM requires fields to be public. I generally don't like VM specific code, but it might be a nice feature if ReflectASM could use Unsafe when available. I'll put it on the (growing :( ) list of Kryo todos.

Thanks!
-Nate

Martin Grotzke

unread,
Jan 11, 2011, 3:08:21 AM1/11/11
to kryo-...@googlegroups.com
On Tue, Jan 11, 2011 at 1:30 AM, Nate <nathan...@gmail.com> wrote:
> 10x is a nice improvement. It sounds about the same difference as ASM versus
> reflection, see chart here:
> http://code.google.com/p/reflectasm/
> The difference being that Unsafe can break the JVM's rules while ReflectASM
> requires fields to be public. I generally don't like VM specific code, but
> it might be a nice feature if ReflectASM could use Unsafe when available.
> I'll put it on the (growing :( ) list of Kryo todos.

As soon as there's an issue I vote this one - 10x sounds definitely cool! :-)

Cheers,
Martin


>
> Thanks!
> -Nate
>
> --
> You received this message because you are subscribed to the "kryo-users"
> group.
> http://groups.google.com/group/kryo-users

--
Martin Grotzke
http://www.javakaffee.de/blog/

Kai

unread,
Jan 11, 2011, 5:26:17 AM1/11/11
to kryo-users
> 10x is a nice improvement. It sounds about the same difference as ASM versus
> reflection, see chart here:http://code.google.com/p/reflectasm/
Yes, bytecode generation via ASM is naturally on par with handwritten
code.
Unsafe might be a little bit slower than bytecode.

> The difference being that Unsafe can break the JVM's rules while ReflectASM
> requires fields to be public.
The Java Reflection Mechanism can/must break the JVM's rules as well
(AccessibleObject.setAccessible(true)) because it is necessary in
order to serialize all fields of an object regardless of the access
modifier. Serialization is a typical cross-cutting concern but where
sacrificing visibility rules does not have a negative effect on
program robustness or quality because it is completely transparent to
the programmer and it does not require the programmer to make a design
decision about making all fields public.
Requiring fields to be public is a greater concern for me, because
that does have a negative effect on design. So you have to plan
upfront that, because of the needs of the serialization library, you
are going to make your fields public, when otherwise you wouldn't do
that.

> I generally don't like VM specific code, but it might be a nice feature if ReflectASM could use Unsafe when available.
I too dislike VM or even worse OS specific code. But in this case when
it is just for performance gains and does not add functionality that
otherwise won't be available on other VM's/OS's, in my optinion, it
could nevertheless be acceptible.

> I'll put it on the (growing :( ) list of Kryo todos.
Many Thanks!

Regards,
Kai
Reply all
Reply to author
Forward
0 new messages