Optimization Strategies around Interface Calls in Java
Asked Answered
M

2

0

I have an application that utilizes a Provider Pattern. The application utilizes the provider implementation by calling interfaces that are defined by the application.

I'm currently researching ways I can optimize my application around interface calls.

I can limit the complexity of my application to the following:

  1. I only need to load the implementation dynamically once on start-up
  2. I only need one provider implementation for a particular set of interfaces for an application instance at any one time.

I would appreciate any strategies people have put into practice to:

  1. Reducing interface calls
  2. Any tricks to generically call the interface implementation classes directly.
  3. Various ways to take better advantage of any compiler optimizations.

Thank you!

Mcnamara answered 27/3, 2011 at 19:29 Comment(3)
I'll cite Donald Knuth at first: "Premature optimization is the root of all evil". Now the question. Do you Really need such optimizations? I was researching how do interface calls work in different JVMs (it was a part of my diploma) and I can say that there is usually no necessity to optimize/reduce them. So if you want to optimize your application, find the real bottleneck at first.Beeves
I agree with xappymah. What kind of application must he be running such that the overhead of calling methods incurs a noticeable performance penalty?!Sara
I agree on the note regarding premature optimization. My standard practice is to build something with a clean design then prioritize optimization on bottle-necks focusing on the algorithm before the constants. I'm actually pondering on building a transactional content storage engine (so calling it an application isn't very accurate). There's a similar system out there that is implemented in C. This question is actually a part of the bigger question that I'm pondering over on: whether or not I should implement this in C or C++ instead of Java.Mcnamara
P
3

Some mis-conceptions worth addressing here.

  1. You can reduce interface calls by calling the underlying concrete implementations directly (or using abstract classes) You should do this when it simplifies the design and improves maintainability (usually more interfaces helps, but not always)

  2. You can cast an interface reference to a concrete reference and use that instead. This is generally bad programing practice and has little impact on performance. Generally you only do this when refactoring properly is more work than its worth. (Its not a good design approach but can be a pragmatic one)

  3. The compiler doesn't optimize the code in any significant way. The few optimizations it does (such as inlining compile time constants) you could probably do without. The JVM does the useful optimizations at runtime. Second guessing what the JVM will do and try to optimise your code is a trail and error process. If you try 10 things which you think should help, 1 will make it significantly faster, 6 will make little difference and 3 will make it slower. i.e. simple code tends to be optimized best.

Unlike C++, most JVMs can optimise out the cost of virtual functions, esp when there is only one or two implementations actually used. i.e. it can optimise code based on how it is used rather than what the compiler can staticly determine.

Placeeda answered 27/3, 2011 at 20:8 Comment(3)
Yep, hotspot heavily tries to reason if it can replace the virtual call, so if you only got one implementation of your interface lying around it'll most certainly optimize it. If you've got different implementations, it gets more complicated though.Prying
Thanks, this is helpful. I wasn't aware that most JVMs optimize the cost of virtual functions when there are few implementations.Mcnamara
It can even inline up to two heavily used methods and still call another virtual method if its not one of those two. ;)Placeeda
S
1

By the sound of it you're doing it the wrong way around.

  1. Well-designed interfaces reduce and not increase application complexity. The interfaces typically used with a provider should help compartmentalise the system. If you feel it would be simpler to access the implementation directly then it's possible that your interfaces need to be redesigned.

  2. The runtime overhead of an "interface call" is so minuscule that you're unlikely to ever be in a situation where it makes the difference between a working and a non-working system.

  3. Generally speaking the Java compiler itself does very little optimisation. The bulk of it happens runtime and therefore the more "natural" your code is, the better the JIT compiler will deal with it. If you try to play tricks to force this optimisation or that (like manually inlining code or reusing variables), you're likely to end up with slower code.

To sum it up; if you want to reduce the complexity of the application, make sure your modules are separated where they should be (the fewer inter-module dependencies you have, the better) and use a code analyser tool to keep track of complexity metrics.

Skyeskyhigh answered 27/3, 2011 at 20:7 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.