See the generated bytecodeTag(s): Varia


Use the javap included in the JDK bin directory. javap is class disassembler, the result is similar to the assembly code but for the JVM.

Consider the following class

class Test1 {
  public static void main(String args[]) {
    new Integer(1);
    new Integer(2);
    new Integer(3);

  }
}
Compile the source code and then disassemble the bytecode with
javap -c Test1
// to redirect the output to a file
javap -c Test1 >test1.out
The Result is
Compiled from "Test1.java"
class Test1 extends java.lang.Object{
Test1();
  Code:
   0:   aload_0
   1:   invokespecial   #1; //Method java/lang/Object."":()V
   4:   return

public static void main(java.lang.String[]);
  Code:
   0:   new #2; //class java/lang/Integer
   3:   dup
   4:   iconst_1
   5:   invokespecial   #3; //Method java/lang/Integer."":(I)V
   8:   pop
   9:   new #2; //class java/lang/Integer
   12:  dup
   13:  iconst_2
   14:  invokespecial   #3; //Method java/lang/Integer."":(I)V
   17:  pop
   18:  new #2; //class java/lang/Integer
   21:  dup
   22:  iconst_3
   23:  invokespecial   #3; //Method java/lang/Integer."":(I)V
   26:  pop
   27:  return
}
and compile the following class and dissassemble the Test2 class.
class Test2 {
  public static void main(String args[]) {
    int i = 1;
    new Integer(i++);
    new Integer(i++);
    new Integer(i++);
  }
}

Compiled from "Test2.java"
class Test2 extends java.lang.Object{
Test2();
  Code:
   0:   aload_0
   1:   invokespecial   #1; //Method java/lang/Object."":()V
   4:   return

public static void main(java.lang.String[]);
  Code:
   0:   iconst_1
   1:   istore_1
   2:   new #2; //class java/lang/Integer
   5:   dup
   6:   iload_1
   7:   iinc    1, 1
   10:  invokespecial   #3; //Method java/lang/Integer."":(I)V
   13:  pop
   14:  new #2; //class java/lang/Integer
   17:  dup
   18:  iload_1
   19:  iinc    1, 1
   22:  invokespecial   #3; //Method java/lang/Integer."":(I)V
   25:  pop
   26:  new #2; //class java/lang/Integer
   29:  dup
   30:  iload_1
   31:  iinc    1, 1
   34:  invokespecial   #3; //Method java/lang/Integer."":(I)V
   37:  pop
   38:  return
}
You can see the "cost" of doing the incrementation of i.

Now with the following source and the disassembled listing

class Test3 {
  public static void main(String args[]) {
    int i = 1;
    new Integer(i++);
    new Integer(i);
    i = i +  1;
    new Integer(i);
  }
}

Compiled from "Test3.java"
class Test3 extends java.lang.Object{
Test3();
  Code:
   0:   aload_0
   1:   invokespecial   #1; //Method java/lang/Object."":()V
   4:   return

public static void main(java.lang.String[]);
  Code:
   0:   iconst_1
   1:   istore_1
   2:   new #2; //class java/lang/Integer
   5:   dup
   6:   iload_1
   7:   iinc    1, 1
   10:  invokespecial   #3; //Method java/lang/Integer."":(I)V
   13:  pop
   14:  new #2; //class java/lang/Integer
   17:  dup
   18:  iload_1
   19:  invokespecial   #3; //Method java/lang/Integer."":(I)V
   22:  pop
   23:  iload_1
   24:  iconst_1
   25:  iadd
   26:  istore_1
   27:  new #2; //class java/lang/Integer
   30:  dup
   31:  iload_1
   32:  invokespecial   #3; //Method java/lang/Integer."":(I)V
   35:  pop
   36:  return
}
"i=i+1" takes 2 op-codes more than the equivalent "i++".

Note this is very low-level optimization, the gain in performance is not very significative, the class is little bit smaller.

Remember Premature optimization is the root of all evil


blog comments powered by Disqus