Blazing Fast Reflection - For Java

Published 14 June 07 06:46 AM | andersnoras 

By accident my main feed, rather than my Java tag feed, was aggregated to Javablogs. This led quite a few Java developers to my post on reflection optimization for .NET. To mend the damage done, I wrote a small sample that uses Hibernate's reflection optimizer to optimize reflection in Java. The design of Hibernate is quite similar to NHibernate, so this was fairly easy to do. The Clonable (it's misspelled in the API) interface in Java is horribly broken, so I didn't do the entire clone thing. Below is an example on how to create a reflection optimizer for a bean.

ArrayList<String> getters = new ArrayList<String>();
ArrayList<String> setters = new ArrayList<String>();
ArrayList<Class> types = new ArrayList<Class>();
Method[] allMethods = Customer.class.getMethods();
for (Method method : allMethods)
{
    if (method.getName().startsWith("get"))
    {
        getters.add(method.getName());
        types.add(method.getReturnType());
        try
        {
            Method setterMethod = Customer.class.getMethod("set" + method.getName().substring(3), method.getReturnType());
            setters.add(setterMethod.getName());
        }
        catch (NoSuchMethodException e)
        {
            setters.add(null);
        }
    }
}

BytecodeProviderImpl bytecodeProvider = new BytecodeProviderImpl();
ReflectionOptimizer optimizer = bytecodeProvider.getReflectionOptimizer(
        Customer.class,
        getters.toArray(new String[0]),
        setters.toArray(new String[0]),
        types.toArray(new Class[0])
);

You can then use the AccessOptimizer to get or set property values, or the InstantiationOptimizer to create new class instances in a similar fashion to what I showed in the .NET post.

Object[] values = optimizer.getAccessOptimizer().getPropertyValues(customer1);
optimizer.getAccessOptimizer().setPropertyValues(customer2, values);

The above snippet shows a basic example of how you can do a shallow clone of any object using Hibernate's reflection optimizer.

The key reason for writing the .NET sample was to show the massive performance improvements optimized reflection has over plain old reflection. So how does Java stack up?

On my laptop, running JUnit 4 inside of IntelliJ IDEA one the Java 1.6 JRE (pew!) it took 21578 milliseconds to assign the values of one instance to another one million times. Using Hibernate's reflection optimizer it took only 79 milliseconds. So we see the same kind of performance improvement in Java as we did on .NET. My biggest surprise was that Java was way faster than .NET; pure reflection on .NET took almost a minute, while light-weight code generation optimized reflection took ~179 milliseconds. To be honest, I expected it to be the other way around.

Filed under:

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Comments

# Anders Nor??s' Blog : Blazing Fast Reflection said on June 14, 2007 3:51 PM:

PingBack from http://andersnoras.com/blogs/anoras/archive/2007/06/13/blazing-fast-reflection.aspx

# Joe Cole said on June 14, 2007 6:02 PM:

Very cool. Something like xstream or objectoutputstream could take advantage of this (perhaps caching field names or the fields themselves) to dramatically increase performance when serialising/deserialising the same class.

Would be very interesting to see what would happen.

# andersnoras said on June 15, 2007 5:51 AM:

@Joe;

I haven't peeked under the covers of Hibernate to examine how reflection optimization is done. (That might be a good topic for a follow up post). However I believe that XStream uses the sun.misc.Unsafe class to do some kinds of optimization when it serializes an object.

# afsina said on June 15, 2007 9:26 AM:

your method seems to have a problem with boolean bean accessors.. i think there is a cleaner way of doing this.. but i am very busy to give an example..

# Anders Norås' Blog said on June 16, 2007 2:04 PM:

With my posts on reflection optimization for .NET and Java , I unconsciously proved a point from an earlier

# Joe said on October 18, 2007 9:08 AM:

It can sometimes get bothersome to extract the good java source code reading from the abominable.

Leave a Comment

(required) 
(optional)
(required) 
Enter the code you see below