11

As per my understanding, use of Java reflection API slows down code execution by orders. But then I see it being used in so many places in Java universe. To name a few :

  • Annotations
  • Spring framework (AOP)
  • Hibernate
  • MyBatis

Which implies that there's some fact about java reflection (aka optimization technique) that I have missed out on. Any pointers ?

Amit Sharma
  • 5,844
  • 5
  • 25
  • 34
  • 1
    "There is some overhead with reflection, but it's a lot smaller Java 5 onwards than it used to be" - how true ? – Amit Sharma May 30 '13 at 07:21

2 Answers2

15

Main point: because they have no other choice.

Java is not a dynamic language, so the only way these frameworks can provide their services is by reflection.

Second, notice that most of the reflection work these framework do happens only once, during initialization, so the runtime performance is not affected.

About the performance of reflection

There is one distinction that I notice being mixed up all the time:

  1. reflective lookup of members;
  2. reflective member access (invocation/read/write).

Number 1 is slow (this is the "orders" you mention); number 2 is the one that has received significant speed improvements and is now only a couple of times slower than native access.

Community
  • 1
  • 1
Marko Topolnik
  • 195,646
  • 29
  • 319
  • 436
  • 1
    +1 for putting the emphasis on the distinction between *lookup* and *access*: the *lookup* is really expensive. – Beryllium May 30 '13 at 07:51
  • 2
    IMO, it would be better to say "no *easy* other choice". Most things that are done using reflection *could in theory* be done by static or dynamic code generation ... or similar complicated techniques that give you statically typed code. But it is hard to justify the pain and the effort ... especially since a framework's reflective overheads are typically small relative to rest of a typical application. – Stephen C May 30 '13 at 08:15
  • Developed test code to test the kind of time _lookup_ and _access_ takes. For those interested, the code is available [here](https://github.com/sharmaak/crashlabs/tree/master/ReflectionTimingTest) Here are the results : - [Class load]: reflection: 3990 ms - [New instance]: reflection: 642 ms - [New instance]: no-reflection: 500 ms - [member find]: reflection: 1890 ms - [Invoke]: reflection: 255 ms - [Invoke]: no-reflection: 237 ms – Amit Sharma Jun 03 '13 at 11:28
3

As a general rule, performance issues should be addressed by profiling. Leaving aside major improvements in reflection performance, all of those frameworks emphasize one-time lookups at startup (or later, in cases of lazy initialization). In the sort of enterprise app that uses them, that's not really relevant. As long as invoke is optimized, most of the penalty will go away.

Andrew Lazarus
  • 18,205
  • 3
  • 35
  • 53