Java how expensive is a method call

I'm a beginner, and I always read that repeating code is bad. However, in order to prevent this from happening, you usually need to have additional method calls. 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 simply copy and paste two lines into my clear () method in the constructor instead of calling the actual method? If so, what's the difference? What if my constructor made 10 method calls, each of which simply set the instance variable to a value? What is the best programming practice?

+55
java performance methods call
Jun 27 2018-11-11T00:
source share
12 answers

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

The compiler can perform this optimization. And so can the JVM. The terminology used by the compiler author and the JVM authors is a “built-in extension”.

If so, then what's the difference?

Measure it. Often you will find that it does not matter. And if you think this is a performance hot spot, you are looking in the wrong place; that you need to measure it.

What if my constructor made 10 method calls, each of which simply set the instance variable to a value?

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

What is the best programming practice?

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

+54
Jun 27 2018-11-18T00:
source share

What everyone else said about optimization is absolutely true.

In terms of performance, there is no reason for the inline method. If this is a performance issue, the JIT in your JVM will enable it. In java, method calls are so close to free that you should not think about it.

Saying, there is another problem. Namely, it is bad programming practice to call an override method (i.e., one that is not final , static or private ) from the constructor. (Effective Java, 2nd ed., P. 89 in an element called “Design and document for inheritance or prohibition of 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 LoggingBinarySearchTree will never be constructive! The problem is that this.callLog will be null when the BinarySearchTree constructor works, but the clear called, which is called, is overridden, and you get a NullPointerException .

Note that Java and C ++ are different here: in C ++, the constructor of the superclass, which calls the virtual method, ends up calling what is defined in the superclass, not the redefined one. People switching between two languages ​​sometimes forget about it.

Given this, I think that perhaps in your case it might be cleaner to embed the clear method when calling from the constructor, but in general, you have to go to Java and make all the method calls that you want.

+13
Jun 27 '11 at 15:37
source share

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

+5
Jun 27 '11 at 3:15 a.m.
source share

Best practice is to measure and cut twice once.

Once you have spent time optimizing the time, you can never return it again! (Measure it first and ask yourself if it’s worth optimizing. How much actual time will you save?)

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

+3
Jun 27 '11 at 3:15 a.m.
source share

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

+3
Jun 27 2018-11-18T00:
source share

Generally speaking (and as a newbie it always means!), You should never do micro-optimizations like the one you are considering. Always maintain code readability over such things.

Why? Because the compiler / access point will do these kinds of optimizations for you on the fly and many, many others. Anyway, when you try to do an optimization on these types of strings (though not in this case), you are likely to do something slower. A point of view understands the general idioms of programming, if you try to do this optimization yourself, it probably won’t understand what you are trying to do, so it won’t be able to optimize it.

There are also significantly higher maintenance costs. If you start repeating the code, it will be much more effort to maintain, which will probably be much more difficult than you think!

As an aside, you can get some moments in your life when you need to do optimization at a low level, but if you click these points, you will definitely know when the time is right. And if you do not, you can always come back and optimize later if you need.

+2
Jun 27 2018-11-18T00:
source share

The pattern that I am following is whether this method satisfies one of the following:

  • Would it be useful for this method to be available outside this class?
  • Would it be helpful to have this method in other methods?
  • Would it be awkward to rewrite this every time I need it?
  • Could the universality of the method be increased using several parameters?

If any of the above values ​​is true, it must be completed in its own method.

+1
Jun 27 2018-11-18T00:
source share

Keep the clear() method as it helps to read. Invalid code is more expensive.

+1
Jun 27 2018-11-18T00:
source share

Optimizing compilers usually does a pretty good job of removing redundancy from these "extra" operations; in many cases, the difference between the "optimized" code and the code is simply written the way you want, and working with the optimizing compiler is not; that is, the optimizing compiler usually does the same good job as you do, and does so without causing any degradation in the source code. In fact, many times, "manually optimized" code ends up EASILY efficient, because the compiler takes many things into account when performing optimizations. 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 Knut

+1
Jun 27 2018-11-18T00:
source share

I would not worry about calling the method, but about the logic of the method. If these were critical systems, and the system was supposed to be “fast,” I would look at optimizing codes that take a lot of time.

0
Jun 27. 2018-11-18T00:
source share

Given the memory of modern computers, it is very inexpensive. It is always better to break the code into methods so that someone can quickly read what is happening. It will also help to reduce errors in the code if the error is limited to one method with the body of several lines.

0
Jun 27 2018-11-18T00:
source share

As others have said, the cost of calling the method is trivial-on-nada, since the compiler optimizes it for you.

However, there are concerns when invoking instance method methods from the constructor. You run the risk of updating the instance method later to try to use an instance variable that has not yet been initiated by the constructor. That is, you do not necessarily want to separate the design work from the designer.

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 will not reset the root of the node. Is this the behavior you want?

0
Jun 27 '11 at 15:38
source share



All Articles