Making Java Reflection field access 40 times faster
Think it can not be done? Think again!
Here is a useful nugget of information that should be common knowledge among performance-conscious Java developers:but based on code I've seen in the wild it might not yet be, hence this entry.
Basically, if you just do this:
Field f = MyBean.class.getDeclaredField("id"); f.set(beanInstance, valueForField);
performance stinks -- setting value is about hundreds of times slower than direct field access. But if you add this little call:
f.setAccessible(true);
in there, overhead is drastically reduced. In a simple micro-benchmark running on my old desktop speed difference is 40x, and while YMMV, it will be an order of magnitude or more and this ratio does not seem to improve with new JVMs (has been steady with 1.4, 1.5 and 1.6). This actually takes overhead down enough so as to make reflection-based access "fast enough" for most use cases: Jackson for example just uses it and does not bother with byte-code generation to create most optimal access (but who knows? maybe it will one day).
So what is the difference? Access checks that would be done by default are heavy-weight, as can be seen from profiler stack traces and JDK sources. And all setAccessible() method does is set a boolean flag that will by-pass these checks. Works for Methods and Constructors as well, although with slightly less pronounced results.
Anyway, thought others might find this useful.