Reflection Efficiency: Quality Byte Code in JVM

Edit 2 : Highly efficient program execution with full object-oriented implementation? Most of the framework written with full force. However, reflection also widely used to achieve it, both for AOP and dependency injection . Using reflection affects performance to a certain extent.

So is it correct to use reflection ? Is there any alternative to reflection from programming language constructs? To what extent should reflection be used?

+7
source share
3 answers

Reflection in and of itself is slow in nature. See this question for more details. There are several reasons for this. John Skeet perfectly explains this:

Check for a constructor without parameters. Check the availability of the constructor without parameters. Make sure the caller has access to use reflection at all. Work out (at run time) how much space you need to assign a call to the constructor code (because it will not know in advance that the constructor is empty)

Basically, reflection should perform all of the above steps before calling, while calling a normal method should do much less.

The JIT code for instantiating B is incredibly lightweight. Basically, it should allocate enough memory (this is just increasing the pointer if GC is not required), and what about that - there is no constructor code to actually call; I don’t know if JIT skips this or not, but in any case it’s not so much.

With that said, there are many cases where Java is not dynamic enough to do what you want, and reflection provides a simple and clean alternative. Consider the following scenario:

  • You have a large number of classes that represent various elements, i.e. Car , Boat and House .
  • They both extend / implement the same class: LifeItem .
  • The user enters one of three lines: "Car", "Boat" or "House".
  • Your goal is to access the LifeItem method based on the parameter.
  • The first approach that comes to mind is to build an if / else structure and build the desired LifeItem . However, it is not very scalable and can become very dirty if you have dozens of LifeItem implementations.

Reflection can help here: it can be used to dynamically build a LifeItem object based on the name, so the input "Car" will be sent to the Car constructor. Suddenly, there could be hundreds of lines of if / else code turning into a simple reflection line. The latter scenario will not be as important on the Java 7+ platform due to the introduction of switch statements with strings, but even then a switch with hundreds of cases is something I would like to avoid. Here what difference between purity will look in most cases:

Without reflection:

 public static void main(String[] args) { String input = args[0]; if(input.equals("Car")) doSomething(new Car(args[1])); else if(input.equals("Boat")) doSomething(new Boat(args[1])); else if (input.equals("House")) doSomething(new House(args[1])); ... // Possibly dozens more if/else statements } 

Considering reflection, it can turn into:

 public static void main(String[] args) { String input = args[0]; try { doSomething((LifeItem)Class.forName(input).getConstructor(String.class).newInstance(args[1])); } catch (Exception ie) { System.err.println("Invalid input: " + input); } } 

Personally, I would say that the latter is more accurate, more concise and more convenient than the first. In the end, this is a personal preference, but this is only one of many cases where reflection is useful.

In addition, when using reflection, you should try to cache as much information as possible. In other words, use simple, logical things, such as not calling the get(Declared)Method everywhere, if you can help it: rather, store it in a variable so that you don't have the overhead of re-linking to a link when you want it use.

So these are the two extremes of pro and con reflection. To summarize, if reflection improves the readability of the code (as in the presented scenario), it will certainly go for it. And if you do, just think about reducing the number of calls to the get* : these are the simplest settings.

+8
source

While reflection is more expensive than the "traditional code", premature optimization is the root of all evil. From decades of empirical data, I assume that a method called with reflection is unlikely to affect performance unless called from a heavy cycle, and even though there have been some performance improvements with reflection:

Some reflective operations, in particular Field, Method.invoke (), Constructor.newInstance (), and Class.newInstance (), have been rewritten for better performance. Reflective calls and instances are several times faster than in previous releases of Improvements in J2SDK 1.4 -

Please note that the lookup method (i.e. Class.getMethod) is not mentioned above, and additional steps, such as moving the class hierarchy when requesting a “declared method” if it is not public, are usually required to select the correct Method object) , so I try to save the method found on a suitable map whenever possible, so the next time the cost will be only the cost of Map.get () and Method.invoke (). I think that any well-written structure can handle this correctly.

It should also be noted that certain optimizations are not possible if reflection is used (for example, leak detection or analysis. Performance improvements for Java HotSpot ™ virtual machines ). But this does not mean that reflection should be avoided at all costs.

However, I believe that the decision to use reflection should be based on other criteria, such as code readability, maintainability, design methods, etc. When using reflection in your own code (as opposed to using a structure that internally uses reflection), one risk turns compile-time errors into temporary errors that are harder to debug. In some cases, you can replace the reflexive call with a traditional OOP pattern, such as Command or Abstract Factory.

+7
source

I can give you one example (but, unfortunately, I can not show the test results, because it was a few months ago). I wrote an XML library (custom project) that replaced some old DOM parser code with classes + annotations. My code was half the size of the original. I did tests, and yes, the reflection was more expensive, but not very (approximately 0.3 seconds out of 14-15 seconds of execution (loss is about 2%)). In places where the code is executed infrequently, reflection can be used with a slight loss of performance.

Also, I'm sure my code can be improved for better performance.

So, I offer the following tips:

  • Use reflection if you can do it beautifully, compactly and concisely;
  • Do not use reflection if your code will be executed many times;
  • Use reflection if you need to project a huge amount of information from another source (for example, XML files) into a Java application;
  • The best use for reflections and annotations is code that runs only once (pre-loaders).
+2
source

All Articles