java how expensive is a method call

30,746

Solution 1

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

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

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

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

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.

Share:
30,746
jhlu87
Author by

jhlu87

Trader learning to program

Updated on July 08, 2022

Comments

  • jhlu87
    jhlu87 almost 2 years

    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?

  • Arafangion
    Arafangion almost 13 years
    It's easier not to ask these questions and just put the darn code in it's own method already!
  • Peaches491
    Peaches491 almost 13 years
    The asker is curious what granularity of his method calls should be. There is no need to create a method to increment an integer if you can just use i++;
  • jhlu87
    jhlu87 almost 13 years
    what is a good way to benchmark? is there some software I can download or do you mean just use System.nanoTime() at the start and end and print the difference?
  • Vineet Reynolds
    Vineet Reynolds almost 13 years
    System.nanoTime() or System.currentTimeMillis is a poor way of doing profiling. You can get a list of profilers from the answer at this Stackoverflow question. I would recommend VisualVM, for it comes with the JDK now.
  • ColinD
    ColinD almost 13 years
    @jhlu87: I think you'd find it very difficult to get an accurate estimate of the overhead of a method call. Microbenchmarking is very hard to get right and even then generally isn't very useful in the grand scheme of things. Read this.
  • Asaf Mesika
    Asaf Mesika about 11 years
    I don't think he was asking for coding style tips but rather knowing if a method call is expensive or not
  • Daniel Martin
    Daniel Martin over 9 years
    He explicity asked "What's the best programming practice?" - as a matter of best practices, this is perfectly relevant.
  • Asaf Mesika
    Asaf Mesika over 9 years
    If you take only the last sentence, you completely lose the context of this question. He wants to know if it is expensive to breakdown you big method into many smaller methods, because a method call has a price. Adding an answer that describes an anti pattern for calling a non final method from a constructor doesn't count as answer to his question as a whole. Oh and check out the title of the question " how expensive is a method call"
  • Dimitar
    Dimitar over 7 years
    @VineetReynolds the linked question is dead.
  • Joffrey
    Joffrey over 4 years
    Actually there is a lot of value in creating a method even if there is not a chance for it to ever be reused. Just giving a name to a block of code and making the overall structure appear is a great benefit in itself.