java how expensive is a method call

JavaPerformanceMethodsCall

Java Problem Overview


I'm a beginner and I've always read that it's bad to repeat code. However, it seems that in order to not do so, you would have to have extra method calls usually. Let's say I have the following class

public class BinarySearchTree<E extends Comparable<E>>{
    private BinaryTree<E> root;
    private final BinaryTree<E> EMPTY = new BinaryTree<E>();
    private int count;
    private Comparator<E> ordering;

    public BinarySearchTree(Comparator<E> order){
        ordering = order;
        clear();
    }

    public void clear(){
        root = EMPTY;
        count = 0;
    }
}

Would it be more optimal for me to just copy and paste the two lines in my clear() method into the constructor instead of calling the actual method? If so how much of a difference does it make? What if my constructor made 10 method calls with each one simply setting an instance variable to a value? What's the best programming practice?

Java Solutions


Solution 1 - Java

> Would it be more optimal for me to just copy and paste the two lines in my clear() method into the constructor instead of calling the actual method?

The compiler can perform that optimization. And so can the JVM. The terminology used by compiler writer and JVM authors is "inline expansion".

> If so how much of a difference does it make?

Measure it. Often, you'll find that it makes no difference. And if you believe that this is a performance hotspot, you're looking in the wrong place; that's why you'll need to measure it.

> What if my constructor made 10 method calls with each one simply setting an instance variable to a value?

Again, that depends on the generated bytecode and any runtime optimizations performed by the Java Virtual machine. If the compiler/JVM can inline the method calls, it will perform the optimization to avoid the overhead of creating new stack frames at runtime.

> What's the best programming practice?

Avoiding premature optimization. The best practice is to write readable and well-designed code, and then optimize for the performance hotspots in your application.

Solution 2 - Java

What everyone else has said about optimization is absolutely true.

There is no reason from a performance point of view to inline the method. If it's a performance issue, the JIT in your JVM will inline it. In java, method calls are so close to free that it isn't worth thinking about it.

That being said, there's a different issue here. Namely, it is bad programming practice to call an overrideable method (i.e., one that is not final, static, or private) from the constructor. (Effective Java, 2nd Ed., p. 89 in the item titled "Design and document for inheritance or else prohibit it")

What happens if someone adds a subclass of BinarySearchTree called LoggingBinarySearchTree that overrides all public methods with code like:

public void clear(){
  this.callLog.addCall("clear");
  super.clear();
}

Then the LoggingBinarySearchTree will never be constructable! The issue is that this.callLog will be null when the BinarySearchTree constructor is running, but the clear that gets called is the overridden one, and you'll get a NullPointerException.

Note that Java and C++ differ here: in C++, a superclass constructor that calls a virtual method ends up calling the one defined in the superclass, not the overridden one. People switching between the two languages sometimes forget this.

Given that, I think it's probably cleaner in your case to inline the clear method when called from the constructor, but in general in Java you should go ahead and make all the method calls you want.

Solution 3 - Java

I would definitely leave it as is. What if you change the clear() logic? It would be impractical to find all the places where you copied the 2 lines of code.

Solution 4 - Java

Generally speaking (and as a beginner this means always!) you should never make micro-optimisations like the one you're considering. Always favour readability of code over things like this.

Why? Because the compiler / hotspot will make these sorts of optimisations for you on the fly, and many, many more. If anything, when you try and make optimisations along these sorts of lines (though not in this case) you'll probably make things slower. Hotspot understands common programming idioms, if you try and do that optimisation yourself it probably won't understand what you're trying to do so it won't be able to optimise it.

There's also a much greater maintenance cost. If you start repeating code then it's going to be much more effort to maintain, which will probably be a lot more hassle than you might think!

As an aside, you may get to some points in your coding life where you do need to make low level optimisations - but if you hit those points, you'll definitely, definitely know when the time comes. And if you don't, you can always go back and optimise later if you need to.

Solution 5 - Java

The best practice is to measure twice and cut once.

Once you've wasted time optimization, you can never get it back again! (So measure it first and ask yourself if it's worth optimisation. How much actual time will you save?)

In this case, the Java VM is probably already doing the optimization you are talking about.

Solution 6 - Java

The cost of a method call is the creation (and disposal) of a stack frame and some extra byte code expressions if you need to pass values to the method.

Solution 7 - Java

The pattern that I follow, is whether or not this method in question would satisfy one of the following:

  • Would it be helpful to have this method available outside this class?
  • Would it be helpful to have this method available in other methods?
  • Would it be frustrating to rewrite this every time i needed it?
  • Could the versatility of the method be increased with the use of a few parameters?

If any of the above are true, it should be wrapped up in it's own method.

Solution 8 - Java

Keep the clear() method when it helps readability. Having unmaintainable code is more expensive.

Solution 9 - Java

Optimizing compilers usually do a pretty good job of removing the redundancy from these "extra" operations; in many instances, the difference between "optimized" code and code simply written the way you want, and run through an optimizing compiler is none; that is to say, the optimizing compiler usually does just as good a job as you'd do, and it does it without causing any degradation of the source code. In fact, many times, "hand-optimized" code ends up being LESS efficient, because the compiler considers many things when doing the optimization. Leave your code in a readable format, and don't worry about optimization until a later time.

> "Premature optimization is the root of > all evil." - Donald Knuth

Solution 10 - Java

I wouldn't worry about method call as much but the logic of the method. If it was critical systems, and the system needed to "be fast" then, I would look at optimising codes that takes long to execute.

Solution 11 - Java

Given the memory of modern computers this is very inexpensive. Its always better to break your code up into methods so someone can quickly read whats going on. It will also help with narrowing down errors in the code if the error is restricted to a single method with a body of a few lines.

Solution 12 - Java

As others have said, the cost of the method call is trivial-to-nada, as the compiler will optimize it for you.

That said, there are dangers in making method calls to instance methods from a constructor. You run the risk of later updating the instance method so that it may try to use an instance variable that has not been initiated yet by the constructor. That is, you don't necessarily want to separate out the construction activities from the constructor.

Another question--your clear() method sets the root to EMPTY, which is initialized when the object is created. If you then add nodes to EMPTY, and then call clear(), you won't be resetting the root node. Is this the behavior you want?

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionjhlu87View Question on Stackoverflow
Solution 1 - JavaVineet ReynoldsView Answer on Stackoverflow
Solution 2 - JavaDaniel MartinView Answer on Stackoverflow
Solution 3 - JavaMarceloView Answer on Stackoverflow
Solution 4 - JavaMichael BerryView Answer on Stackoverflow
Solution 5 - JavaArafangionView Answer on Stackoverflow
Solution 6 - JavaAndreas DolkView Answer on Stackoverflow
Solution 7 - JavaPeaches491View Answer on Stackoverflow
Solution 8 - JavaFabian BarneyView Answer on Stackoverflow
Solution 9 - JavaPaul SonierView Answer on Stackoverflow
Solution 10 - JavaBuhake SindiView Answer on Stackoverflow
Solution 11 - JavaadamjmarkhamView Answer on Stackoverflow
Solution 12 - JavaMatthew FlynnView Answer on Stackoverflow