1

Which one is more optimal or is there any difference at all?

String s = methodThatReturnsString(); int i = methodThatReturnsInt(); thirdMethod(s, i); 

or

thirdMethod(methodThatReturnsString(), methodThatReturnsInt()); 

By optimal I mean optimal in the terms of memory usage etc.

5
  • 18
    If there is a difference, it isn't worth bothering about. Commented Jan 14, 2010 at 11:54
  • 3
    And said difference would depend on the compiler used. Compiler optimization may even result in the exact same code if neither s nor i are used after that. I would make my decision based on readability instead. Commented Jan 14, 2010 at 11:55
  • 1
    you could try compiling both and comparing the byte code Commented Jan 14, 2010 at 12:05
  • 2
    First, "optimal" is not a property that can be "more" or "less". Either something is optimal or it isn't. Instead of "more optimal" you seem to mean "better" or "more efficient". Second, don't misspell names in programs; it is "method", always. Commented Jan 14, 2010 at 12:26
  • 1
    It is hard to imagine a more trifling performance question than this. As a Java programmer, I cannot stress emphatically enough how much it is NOT YOUR JOB to distinguish between these obviously-equivalent constructs. Commented Jan 15, 2010 at 0:21

9 Answers 9

15

It has nothing to do with optimization here, but it's more a question of readability of your code...

Sign up to request clarification or add additional context in comments.

2 Comments

Absolutely, but keep in mind people may disagree on whether the first or second is more readable.
Yes, you are right. However, it is still a question of readability here ;)
11

Which one is more optimal?

The one which is easier to read :-)

I would think that any difference is optimized away when compiled (provided that the declared variables are not used afterwards - i.e. the solutions are otherwise identical).

Comments

10

I highly suspect that both forms are identical, but don't take my word for it. Let's find out ourselves! :D

public class Tests { public void test1() { String s = methodThatReturnsString(); int i = methodThatReturnsInt(); thirdMethod(s, i); } public void test2() { thirdMethod(methodThatReturnsString(), methodThatReturnsInt()); } public String methodThatReturnsString() { return ""; } public int methodThatReturnsInt() { return 0; } public void thirdMethod(String s, int i) { } } 

Let's compile it:

 > javac -version javac 1.6.0_17 > javac Tests.java 

Now, let's print out the bytecode instructions!

 > javap -c Tests Compiled from "Tests.java" public class Tests extends java.lang.Object{ public Tests(); Code: 0: aload_0 1: invokespecial #1; //Method java/lang/Object."":()V 4: return public void test1(); Code: 0: aload_0 1: invokevirtual #2; //Method methodThatReturnsString:()Ljava/lang/String; 4: astore_1 5: aload_0 6: invokevirtual #3; //Method methodThatReturnsInt:()I 9: istore_2 10: aload_0 11: aload_1 12: iload_2 13: invokevirtual #4; //Method thirdMethod:(Ljava/lang/String;I)V 16: return public void test2(); Code: 0: aload_0 1: aload_0 2: invokevirtual #2; //Method methodThatReturnsString:()Ljava/lang/String; 5: aload_0 6: invokevirtual #3; //Method methodThatReturnsInt:()I 9: invokevirtual #4; //Method thirdMethod:(Ljava/lang/String;I)V 12: return public java.lang.String methodThatReturnsString(); Code: 0: ldc #5; //String 2: areturn public int methodThatReturnsInt(); Code: 0: iconst_0 1: ireturn public void thirdMethod(java.lang.String, int); Code: 0: return } 

I thought this looked a bit strange - test1() and test2() are different. It looks like the compiler is adding the debugging symbols. Perhaps this is forcing it to explicitly assign return values to the local variables, introducing extra instructions.

Let's try recompiling it with no debugging:

 > javac -g:none Tests.java > javap -c Tests public class Tests extends java.lang.Object{ public Tests(); Code: 0: aload_0 1: invokespecial #1; //Method java/lang/Object."":()V 4: return public void test1(); Code: 0: aload_0 1: invokevirtual #2; //Method methodThatReturnsString:()Ljava/lang/String; 4: astore_1 5: aload_0 6: invokevirtual #3; //Method methodThatReturnsInt:()I 9: istore_2 10: aload_0 11: aload_1 12: iload_2 13: invokevirtual #4; //Method thirdMethod:(Ljava/lang/String;I)V 16: return public void test2(); Code: 0: aload_0 1: aload_0 2: invokevirtual #2; //Method methodThatReturnsString:()Ljava/lang/String; 5: aload_0 6: invokevirtual #3; //Method methodThatReturnsInt:()I 9: invokevirtual #4; //Method thirdMethod:(Ljava/lang/String;I)V 12: return public java.lang.String methodThatReturnsString(); Code: 0: ldc #5; //String 2: areturn public int methodThatReturnsInt(); Code: 0: iconst_0 1: ireturn public void thirdMethod(java.lang.String, int); Code: 0: return } 

Inconceivable!

So, according to my compiler (Sun JDK), the bytecode is shorter for the second version. However, the virtual machine will probably optimize any differences away. :)

Edit: Some extra clarification courtesy of Joachim Sauer's comment:

It's important to note that the byte code tells only half the story: How it is actually executed depends a lot on the JVM (that's quite different to C/C++, where you can see the assembler code and it's exactly how it's executed). I think you realize that, but I think it should be made clearer in the post.

3 Comments

It's important to note that the byte code tells only half the story: How it is actually executed depends a lot on the JVM (that's quite different to C/C++, where you can see the assembler code and it's exactly how it's executed). I think you realize that, but I think it should be made clearer in the post.
@Joachim: I wholeheartedly agree! I have added your comment to the answer.
++ For taking the time to walk through it. The only thing I don't hear is anyone saying that the relevance of the difference depends on how much work goes on inside the functions. For typical functions, the difference you found could easily be in the noise.
6

I would prefer the first option. However this has nothing to do with speed, but with debuggability. In the second option I can not easily check what the values of s and i are. Performance-wise this will not make any difference at all.

Comments

1

There shouldn't be any difference. Both the temporarily used String and int have to reside somewhere and Java is, internally, a stack machine. So regardless of whether you give the return values of that method calls names or not, they have to be stored on the stack prior to execution of thirdMethod(String, int).

Implications of that for the resulting JITted code can be hard to find. That's on a completely different level ob abstraction.

If in doubt, profile. But I wouldn't expect any difference here.

Comments

1

It is the same thing. In both cases the same functions will be called and variables (automatic or explicitly defined will be allocated). The only difference is that in the second case, the variables will be ready to garbage collected whereas on the first one you need to wait to get out of scope.

Of course however the first one is much more readable.

2 Comments

-1 Assertion about GC is not true. In practice, nothing really gets collected until the method exits anyway. (Using a newish openJDK)
Yes, but in the first version the variables s and i won't be garbage collectable even after the method has exited. What will happen depends on the wrapping code.
0

There is no difference at all. In this case, you might want to consider readability and clearness.

Comments

0

Experiment and measure. If speed is what matters, measure speed. If memory usage matters, measure memory usage. If number of bytecode instructions is what matters, count bytecode instructions. If code readability is what matters, measure code readability. Figuring out how to measure code readability is your homework.

If you don't experiment and measure all you get will be opinion and argument.

Or, if you are very lucky, someone on SO will run your experiments for you.

PS This post is, of course, my opinion and argument

Comments

-2

thirdMethod(metodThatReturnsString(), metodThatReturnsInt());

is more optimal...

1 Comment

you can use two variables s and i for future use in the same program

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.