Java之深入JVM(1) - 由i++ 和 ++i的执行速度所想到的

java

i++

++i



i-=-1



i+=1

以上的四句代码,问那句的执行速度更快?

对于C/C++程序员来说,可能首先想到的就是i++和++i要比其他两者要快一些,但是在Java中是不是这样的呢?

我们可以对他进行一些分析,首先当然想到的是对这些语句利用Java的System.currentTimeMillis()计算单个语句运行很多次(如10亿次)后的时间,然后作比较.

例如这样:

测试环境:(1)Windows XP sp3 (2)JDK "1.6.0_07"   Client VM (build 10.0-b23, mixed

mode, sharing)

Increment {


    public int preIncrement() {
        int i = 0;
       

++i;


        return i;
    }

    public int postIncrement() {


        int i = 0;
        i++;
       

return

i;
    }

    public int negative() {
        int i = 0;
        i

-= -1;
       

return

i;
    }

    public int plusEquals() {
        int i = 0;

        i

+= 1;
        return i;
    }



    public static void main(String[] args) {
        Increment in

= new Increment();
        long start

=

System.currentTimeMillis();
        for (int i = 0; i < 1000000000;

i++) {


            in.preIncrement();
        }

       

System.out.println("preIncrement:"
               

+

(System.currentTimeMillis() - start));

        start =

System.currentTimeMillis();
        for (int i = 0; i < 1000000000;

i++) {


            in.postIncrement();
        }

       

System.out.println("postIncrement:"
               

+

(System.currentTimeMillis() - start));

        start =

System.currentTimeMillis();
        for (int i = 0; i < 1000000000;

i++) {


            in.negative();
        }

       

System.out.println("negative:" +

(System.currentTimeMillis() - start));

        start =

System.currentTimeMillis();
        for (int i = 0; i < 1000000000;

i++) {


            in.plusEquals();
        }

        System.out


                .println("plusEquals:" +

(System.currentTimeMillis() - start));

    }
}

运行结果,发现四次结果都不一样但是差别极其微小,如图:

但是这样我们是不是就可以说,这四个语句的运行在Java中是有差别或者是无差别的呢?当然不能这样去说,这个程序的具体运行还受限于当前机器的所运行的其他程序以及JVM中的JIT引擎对执行代码的优化等。

其实一个比较合理的办法利用Javap反汇编这个文件,去看看反汇编后各个方法所生成的字节码,由于JVM在运行的时候就是执行这些中间代码,所以比较能够说明问题.

然后我运行javap –c –v

com.jni.test.tracker.object.Increment去反汇编这个代码,得到了preIncrement,postIncrement,negative,plusEquals方法各自的字节码如下:

public int preIncrement(); 

Code:

Stack=1, Locals=2, Args_size=1

0: iconst_0

1: istore_1

2: iinc 1, 1

5: iload_1

6: ireturn

LineNumberTable:

line 5: 0

line 6: 2

line 7: 5

LocalVariableTable:

Start Length Slot Name Signature

0 7 0 this Lcom/jni/test/tracker/object/Increment;

2 5 1 i I

public int postIncrement();

Code:

Stack=1, Locals=2, Args_size=1

0: iconst_0

1: istore_1

2: iinc 1, 1

5: iload_1

6: ireturn

LineNumberTable:

line 11: 0

line 12: 2

line 13: 5

LocalVariableTable:

Start Length Slot Name Signature

0 7 0 this Lcom/jni/test/tracker/object/Increment;

2 5 1 i I

public int negative();

Code:

Stack=1, Locals=2, Args_size=1

0: iconst_0

1: istore_1

2: iinc 1, 1

5: iload_1

6: ireturn

LineNumberTable:

line 17: 0

line 18: 2

line 19: 5

LocalVariableTable:

Start Length Slot Name Signature

0 7 0 this Lcom/jni/test/tracker/object/Increment;

2 5 1 i I

public int plusEquals();

Code:

Stack=1, Locals=2, Args_size=1

0: iconst_0

1: istore_1

2: iinc 1, 1

5: iload_1

6: ireturn

LineNumberTable:

line 23: 0

line 25: 2

line 26: 5

LocalVariableTable:

Start Length Slot Name Signature

0 7 0 this Lcom/jni/test/tracker/object/Increment;

2 5 1 i I

令人惊讶的是,虽然这四个方法是不一样的,但是经过Java编译器优化后,我们发现生成的四个方法的bytecode实际都是一样的。

下面简单讲解一下这几句bytecode

iconst_0:将int类型的值0压入栈

istore_1: 从栈中弹出int类型值,然后将其存到位置为0的局部变量中

iinc 1,1 : 为局部变量中位置为1的int数 加1

iload_1 : 将局部变量中位置为1的int变量入栈

ireturn : 从栈中弹出int类型值。

 

 

 

以上是 Java之深入JVM(1) - 由i++ 和 ++i的执行速度所想到的 的全部内容, 来源链接: utcz.com/z/391844.html

回到顶部