Consider two methods in Java, one generates an object as output that is used as an input for another method like so:
// method 1 generating the input for method 2
public Object generate() {
return new Object();
}
// method 2 using the output of method 1 as input
public void use(Object o) {
// ...
}
For chaining these methods there are now two obvious options:
- Store the output of the
generate()
method in a new object and pass that object to theuse()
method:
Object o = generate();
use(o);
- Call the
generate()
method directly inside the parenthesis of theuse()
method:
use(generate());
I am personally in favor of option 1) because this code is much clearer to me. There is only a single thing happening in each line which makes it easier for other programmers to understand the code. When I started programming, everyone was keen on writing code in as few lines as possible but now I prefer more lines over few if this helps to make the code easier to understand.
Are there performance issues when using option 1) instead of option 2)?
As far as I understand the principles of Java, the Object generated by the generate()
method has to allocate memory regardless and assigning it explicitly to a variable will only create a new pointer to this object which should not impact performance. Is this assumption correct?
CodePudding user response:
Short answer would be: in your case they are the same
Generally speaking function calls are expensive. Each call puts stuff on the call stack, jumps the instruction pointer around and creates the rough equivalent of brand new variables anyway. So meaning that if you can avoid calling function multiple times by using a variable you can actually be more efficient by calling it once and storing it in variable. So in your example it is pretty much the same. And in general if are sacrificing much readability for a micro optimization it is not usually worth it
CodePudding user response:
There might be a theoretical performance impact, as the first example you mentioned will produce slightly more ops in the bytecode (you can check this with javap -c Test.class
):
Code:
0: invokestatic #19 // Method generate:()Ljava/lang/Object;
3: astore_1
4: aload_1
5: invokestatic #25 // Method use:(Ljava/lang/Object;)V
8: return
As opposed to your second example:
Code:
0: invokestatic #19 // Method generate:()Ljava/lang/Object;
3: invokestatic #25 // Method use:(Ljava/lang/Object;)V
6: return
In practice, there won't be any difference or performance issues.
Best practice is what is most readable.