Java Method invocation vs using a variable

JavaPerformance

Java Problem Overview


Recently I got into a discussion with my Team lead about using temp variables vs calling getter methods. I was of the opinion for a long time that, if I know that I was going to have to call a simple getter method quite a number of times, I would put it into a temp variable and then use that variable instead. I thought that this would be a better both in terms of style and performance. However, my lead pointed out that in Java 4 and newer editions, this was not true somewhat. He is a believer of using a smaller variable space, so he told me that calling getter methods had a very negligible performance hit as opposed to using a temp variable, and hence using getters was better. However, I am not totally convinced by his argument. What do you guys think?

Java Solutions


Solution 1 - Java

Never code for performance, always code for readability. Let the compiler do the work.

They can improve the compiler/runtime to run good code faster and suddenly your "Fast" code is actually slowing the system down.

Java compiler & runtime optimizations seem to address more common/readable code first, so your "Optimized" code is more likely to be de-optimized at a later time than code that was just written cleanly.

Note:

This answer is referring to Java code "Tricks" like the question referenced, not bad programming that might raise the level of loops from an O(N) to an O(N^2). Generally write clean, DRY code and wait for an operation to take noticeably too long before fixing it. You will almost never reach this point unless you are a game designer.

Solution 2 - Java

Your lead is correct. In modern versions of the VM, simple getters that return a private field are inlined, meaning the performance overhead of a method call doesn't exist.

Solution 3 - Java

Don't forget that by assigning the value of getSomething() to a variable rather than calling it twice, you are assuming that getSomething() would have returned the same thing the second time you called it. Perhaps that's a valid assumption in the scenario you are talking about, but there are times when it isn't.

Solution 4 - Java

It depends. If you would like to make it clear that you use the same value again and again, I'd assign it to a temp variable. I'd do so if the call of the getter is somewhat lengthy, like myCustomObject.getASpecificValue().

You will get much fewer errors in your code if it is readable. So this is the main point.

The performance differences are very small or not existent.

Solution 5 - Java

If you keep the code evolution in mind, simple getters in v1.0 tend to become not-so-simple getters in v2.0.

The coder who changes a simple getter to not-so-simple getter usually has no clue that there is a function that calls this getter 10 times instead of 1 and never corrects it there, etc.

That's why from the point of view of the DRY principal it makes sense to cache value for repeated use.

Solution 6 - Java

I will not sacrifice "Code readability" to some microseconds.
Perhaps it is true that getter performs better and can save you several microseconds in runtime. But i believe, variables can save you several hours or perhaps days when bug fixing time comes.

Sorry for the non-technical answer.

Solution 7 - Java

I think that recent versions of the JVM are often sufficiently clever to cache the result of a function call automatically, if some conditions are met. I think the function must have no side effects and reliably return the same result every time it is called. Note that this may or may not be the case for simple getters, depending on what other code in your class is doing to the field values.

If this is not the case and the called function does significant processing then you would indeed be better of caching its result in a temporary variable. While the overhead of a call may be insignificant, a busy method will eat your lunch if you call it more often than necessary.

I also practice your style; even if not for performance reasons, I find my code more legible when it isn't full of cascades of function calls.

Solution 8 - Java

It is not worth if it is just getFoo(). By caching it into a temp variable you are not making it much faster and maybe asking for trouble because getFoo() may return different value later. But if it is something like getFoo().getBar().getBaz().getSomething() and you know the value will not be changed within the block of code, then there may be a reason to use temp variable for better readability.

Solution 9 - Java

A general comment: In any modern system, except for I/O, do not worry about performance issues. Blazing fast CPUs and heaps of memory mean, all other issues are most of the time completely immaterial to actual performance of your system. [Of course, there are exceptions like caching solutions but they are far and rare.]

Now coming to this specific problem, yes, compiler will inline all the gets. Yet, even that is not the actual consideration, what should really matter is over all readability and flow of your code. Replacing indirections by a local variable is better, if the call used multiple times, like customer.gerOrder().getAddress() is better captured in local variable.

Solution 10 - Java

The virtual machine can handle the first four local variables more efficiently than any local variable declared after that (see lload and lload_<n> instructions). So caching the result of the (inlined) getter may actually hurt your performance.

Of course on their own either performance influence is almost negligible so if you want to optimize your code make sure that you are really tackling an actual bottleneck!

Solution 11 - Java

Another reason to not use a temporary variable to contain the result of a method call is that using the method you get the most updated value. This could not be a problem with the actual code, but it could become a problem when the code is changed.

Solution 12 - Java

I am in favour of using temp variable if you are sure about getter will return same value throughout the scope. Because if you have a variable having name of length 10 or more getter looks bad in readability aspect.

Solution 13 - Java

I've tested it in a very simple code :

  • created a class with a simple getter of an int (I tried both with final and non-final value for Num, didn't see any difference, mind that it's in the case num never change also...!):

      Num num = new Num(100_000_000);
    
  • compared 2 differents for loops:

      1: for(int i = 0; i < num.getNumber(); ++i){(...)}
    
      2: number = num.getNumber();
      for(int i = 0; i < number; ++i){(...)}
    

The result were around 3 millis int the first one and around 2 millis in the second one. So there's a tiny difference, nothing to worry about for small loops, may be more problematic on big iterations or if you always call getter and need them a lot. For instance, in image processing if you want to be quick, don't use repetively getters I would advise...

Solution 14 - Java

I'm +1 for saving the variable.

  1. Readability over performance - your code is not just for you.
  2. Performance might be negligible but not all the time. I think it is important to be consistent and set a precedent. So, while it might not matter for one local variable - it could matter in a larger class using the same value multiples times or in the case of looping.
  3. Ease of changing implementation/ avoiding DRY code. For now you get the value from this one place with a getter and theoretically you use the getter 100 times in one class. But in the future - if you want to change where/how you get the value - now you have to change it 100 times instead of just once when you save it as an instance variable.

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
QuestionSeagullView Question on Stackoverflow
Solution 1 - JavaBill KView Answer on Stackoverflow
Solution 2 - JavaRandolphoView Answer on Stackoverflow
Solution 3 - JavaPaul ClaphamView Answer on Stackoverflow
Solution 4 - JavatangensView Answer on Stackoverflow
Solution 5 - JavaAlexander PogrebnyakView Answer on Stackoverflow
Solution 6 - JavaHendra JayaView Answer on Stackoverflow
Solution 7 - JavaCarl SmotriczView Answer on Stackoverflow
Solution 8 - JavafastcodejavaView Answer on Stackoverflow
Solution 9 - Javauser234054View Answer on Stackoverflow
Solution 10 - JavaBombeView Answer on Stackoverflow
Solution 11 - JavaapadernoView Answer on Stackoverflow
Solution 12 - JavaRhushikesh ChaudhariView Answer on Stackoverflow
Solution 13 - JavaNicolas ZimmermannView Answer on Stackoverflow
Solution 14 - JavaDLindzView Answer on Stackoverflow