I have these 2 codes in Java and C++, which are supposed to do the same thing.
My intuition was that the size (and also content) of object code would be the same for R1 and R2. It's the case for the C++ (difference of 4 bytes if compiled without -O1). There is a bigger difference for the Java bytecode (R2 is longer), which is surprising for me.
Maybe I'm not looking at the right things and my question might not be relevant, but is it normal that the Java bytecode is so "close" from the source code, and does it mean that it's always more "efficient"/"optimized" to write everything in one-line instead of using local variables ?
C++
int A(int a) { return 0; } int B(int b) { return 0; } int C(int c) { return 0; } int D(int d) { return 0; } int R1() { return A(B(C(3)+D(3))); } int R2() { int d = D(3); int c = C(3); int b = B(c + d); return A(b); } // Then R1() and R2() are called in the main() Java
class MyClass { static int A(int a) { return 0; } static int B(int b) { return 0; } static int C(int c) { return 0; } static int D(int d) { return 0; } static int R1() { return A(B(C(3)+D(3))); } static int R2() { int d = D(3); int c = C(3); int b = B(c + d); return A(b); } // Then R1 and R2 are called in the Main() } When I compiled both of them (g++ -O1 version 9.4 and javac version 11.0.17), and disassemble R1 and R2, I get this:
C++ (g++ -O1 prog.cpp)
R1: 1251: f3 0f 1e fa endbr64 1255: 53 push %rbx 1256: bf 03 00 00 00 mov $0x3,%edi 125b: e8 9d ff ff ff callq 11fd <_Z1Ci> 1260: 89 c3 mov %eax,%ebx 1262: bf 03 00 00 00 mov $0x3,%edi 1267: e8 bb ff ff ff callq 1227 <_Z1Di> 126c: 8d 3c 03 lea (%rbx,%rax,1),%edi 126f: e8 5f ff ff ff callq 11d3 <_Z1Bi> 1274: 89 c7 mov %eax,%edi 1276: e8 2e ff ff ff callq 11a9 <_Z1Ai> 127b: 5b pop %rbx 127c: c3 retq R2: <exact same as R1> Java (javap -c MyClass)
javap -c Appel static int R1(); Code: 0: iconst_3 1: invokestatic #8 // Method C:(I)I 4: iconst_3 5: invokestatic #9 // Method D:(I)I 8: iadd 9: invokestatic #10 // Method B:(I)I 12: invokestatic #11 // Method A:(I)I 15: ireturn static int R2(); Code: 0: iconst_3 1: invokestatic #9 // Method D:(I)I 4: istore_0 5: iconst_3 6: invokestatic #8 // Method C:(I)I 9: istore_1 10: iload_1 11: iload_0 12: iadd 13: invokestatic #10 // Method B:(I)I 16: istore_2 17: iload_2 18: invokestatic #11 // Method A:(I)I 21: ireturn
Aand friends do and the output is identical. Well, almost identical. Good enough for me.