A few weeks ago I found the small, but impressive Java Library reflectASM. I stumbled over it while looking for a way to optimize reflection code within a small framework I’m working on.
First of all I want to say that you should always check if you really need Java’s Reflection API. Reflection is powerful, but everything comes with a prize – in this case: performance loss. So the best optimization you can get is just not use it at all (if you not really need it). That is by the way always a good optimization strategy: “Do I really need that? No, then get rid of it!”
Since you need reflection within your code (I assume that, because otherwise you would have followed the upper strategy by leaving the page 😉 ), let’s talk about how you can minimize the performance drawback with reflectASM. I’ll use for demonstration purposes the following class:
The below code snippet shows how method a() is called on an instance of MyClass using Reflection and in comparison using ReflectASM.
Looks quite the same for me, except of line 9. Why is then the reflectASM code much faster than using reflection? In case of method access, it is ~ 50% less execution time.
It’s really simple when you have a look on the below code snippet. This is the generated access class of which an object is returned from calling MethodAccess.get(MyClass.class), cf. line 8 in the upper code snippet. The invocation of method invoke(…), cf. line 10 in the upper code snippet, calls the method directly on the passed object which is much faster than using Reflection, even if some casting is necessary.
Generated access class (returned by MethodAccess.get(MyClass.class)
thrownewIllegalArgumentException("Method not found: "+paramInt);
You’ll also see why I used an methodIndex for method a() in the upper example. The methods are separated into different case blocks, meaning that in the example the methodAccess.invoke(…) is called with methodIndex = 1 (for method parameter paramInt). You could also pass one of the method names “a” or “b” into the method invoke(…). But then reflectASM first needs to find out the methodIndex, which is of course a little bit slower.
So, how easy is that!
Thanks Nathan for this useful and easy to use library.