Is overloading methods less performatic?

Asked

Viewed 229 times

12

I was reading about interfaces as part of my studies and came across an overloaded class (overloading) methods, with two comments saying that it should be avoided. I was in doubt about it affecting performance. It affects?

4 answers

9

No. The performance should be the same. The method to be called is decided at the time of compilation, based on the types of arguments, since these are already known at that time. You can imagine that each method with the same name is translated into a method with a unique name in bytecode, and each call to them is replaced by the call to the corresponding method. You can see so you don’t have to stop the call to check tables or something.

Note that this is different from overlapping (Overriding). In this case, it is necessary to decide at runtime which method should be called (as specific as possible in the case). This is done by looking at virtual call tables, which adds a cost.

Anyway, as always when it comes to performance, the best thing to do is to worry about writing the most clear and clean code possible, avoiding premature optimizations. If once the performance is done, you should take measures to identify where the "bottleneck" of your application is. It’s not usually in that kind of detail.

9

The overload itself does not affect performance because they are methods like any other, they have nothing special but the fact that there is the same name, but all this is decided at compilation time not generating running cost.

May slightly increase compile time, but derisory.

What may occur is that it is normal in such cases for an overloaded method to call another of the overload by passing some extra argument or making a preparation before or treating the result afterwards. In this case there may be a small overhead call for a new method. But you may also not have because the compiler and the Jitter are smart enough to optimize this, if it’s worth it and possible.

Anyway the alternative would be the duplication of code that is bad for maintenance, eventually violating the DRY.

Don’t be afraid to use the overload where it makes sense. Just don’t use it if the methods do different things. The overload should be used when the same action will be performed with different input data.

It may be that the comment referred to something else. If you had access to the code to see the context would be to respond better.

7


It does not affect performance as the method that will be invoked can be determined at compile time.

Perhaps the author of the commentary was referring to avoid abusing overloading, because it can worsen readability.

  • That’s probably what he was talking about. Thanks for the clarification.

2

On performance in Java method calls, first I would say not to worry so strongly about the subject, to leave to worry when the performance is a real bottleneck. Secondly, I would say that your algorithm is wrong. But it also costs nothing to know a little the functioning of the JVM, right?

When you compile a Java code, it generates JVM bytecodes. When there is a method/function call, the compiler places a method invocation bytecode. I quickly remember the following invocations:

  • invokeStatic: for static methods; the Binding is done at compilation level, not needing to do a very large search;
  • invokeSpecial: for private constructors and methods; also decided in the compilation;
  • invokeVirtual: for class method calls, used to do polymorphism; it is only possible to do the Binding at execution level, then the JVM does a search in the class method table, which implies a little more time;
  • invokeInterface: for method calls from an interface; similar to invokeVirtual, only at implementation level.

Examples of when invocations occur

public interface Suricate {
  int seboso();
}

public class Marmota implements Suricate {
  @Override
  public int seboso() {
    return 1;
  }

  @Override
  public String toString() {
    return "marmota";
  }

  public Marmota() {
    System.out.println(seboso() + prvt() + sttc());
  }

   private int prvt() {
     return 4;
  }

  static int sttc() {
    return 5;
  }

  public int somaSeboso(Suricate s) {
    return seboso() + s.seboso();
  }
}

When calling new Marmota(), there is a invokeSpecial calling the builder.

Inside the constructor, there is the call for 3 methods from within the class: "

  • seboso(), called with invokeVirtual
  • prvt(), called with invokeSpecial
  • sttc(), called with invokeStatic

When calling somaSeboso, there are two methods calls:

  • seboso(), which is the same thing as this.seboso(), called with invokeVirtual
  • s.seboso(), which is called through the invokeInterface

The summoning speed in terms of speed is (faster first):

  • invokeStatic
  • invokeSpecial
  • invokeVirtual
  • invokeInterface

I don’t remember if there’s any relationship between invokeStatic and invokeSpecial

I also don’t know how invokeDynamics of Java 7 fits this relationship

Jitter can also positively affect performance

This is just a general reminder of the expected execution of the methods invocation, do not try to force a method that should naturally be called via invokeVirtual to be called as invokeSpecial. It is not very positive that you force different levels of abstraction from those that are natural to your program.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.