zoukankan      html  css  js  c++  java
  • JAVA的i++, i+=1, i=i+1有区别吗?

    看一些JAVA基础题的时候,经常看到这个问题,很多人的解释是:i++最快,i+=1其次,i=i+1最慢。下面通过Sun JDK编译出来的字节码验证一下这个问题。

    为了让编译出来的字节码便于阅读,将这三个表达式分别写在一个方法里面:

     1     private void a(){
     2         int i=0;
     3         i += 1;
     4     }
     5     
     6     private void b(){
     7         int i=0;
     8         i++;
     9     }
    10     
    11     private void c(){
    12         int i=0;
    13         i=i+1;
    14     }

    编译之后(SUN JDK1.7),再看编译出来的字节码(直接把.class文件用IDE打开,或者用javap -v -p classFileName命令):

    // Method descriptor #6 ()V
      // Stack: 1, Locals: 2
      private void a();
        0  iconst_0
        1  istore_1 [i]
        2  iinc 1 1 [i]
        5  return
          Line numbers:
            [pc: 0, line: 15]
            [pc: 2, line: 16]
            [pc: 5, line: 17]
          Local variable table:
            [pc: 0, pc: 6] local: this index: 0 type: com.leo.javabasis.Add
            [pc: 2, pc: 6] local: i index: 1 type: int
      
      // Method descriptor #6 ()V
      // Stack: 1, Locals: 2
      private void b();
        0  iconst_0
        1  istore_1 [i]
        2  iinc 1 1 [i]
        5  return
          Line numbers:
            [pc: 0, line: 20]
            [pc: 2, line: 21]
            [pc: 5, line: 22]
          Local variable table:
            [pc: 0, pc: 6] local: this index: 0 type: com.leo.javabasis.Add
            [pc: 2, pc: 6] local: i index: 1 type: int
      
      // Method descriptor #6 ()V
      // Stack: 1, Locals: 2
      private void c();
        0  iconst_0
        1  istore_1 [i]
        2  iinc 1 1 [i]
        5  return
          Line numbers:
            [pc: 0, line: 25]
            [pc: 2, line: 26]
            [pc: 5, line: 27]
          Local variable table:
            [pc: 0, pc: 6] local: this index: 0 type: com.leo.javabasis.Add
            [pc: 2, pc: 6] local: i index: 1 type: int

    这三个方法的字节码是一样的(除了行号),先稍微解释一下这段字节码指令:

    iconst_0 //整数常量0入栈
    istore_1 //将栈上的值出栈,保存到序号为1的局部变量(也就是i)
    iinc 1 1 //将序号为1的局部变量增加1,此指令语法为iinc index const。
    是不是SUN JDK在某一个版本之前是没有对这个问题进行优化?找了一个能用的SUN JDK 1.3再试了一下(1.1, 1.2跑不动了),编译出来的结果,方法a、b的字节码和1.7下是一样的。但是c的就不一样了:
    Method void c()
       0 iconst_0
       1 istore_1
       2 iload_1
       3 iconst_1
       4 iadd
       5 istore_1
       6 return

    指令行2-5的作用分别是:

    iload_1 //将序号为1的局部整数变量入栈
    iconst_1 //整数常量1入栈
    iadd //使用栈上的两个整数值出栈进行加法运算,将结果入栈
    istore_1 //将栈上的整数值保存到序号为1的局部变量
    这种方式同样达到了相加的目的,但是相比直接iinc指令,还是绕了很多,效率自然不会好。

    由此看来,在某一个版本之后,编译器是对这个问题进行了优化。关于谁的效率好的问题,在现在的SUN JDK版本中已经没有差别了(即使是使用1.7的JDK编译出的1.3JRE兼容的字节码,方法c也是优化过的),
    但是曾经某个时代确实是有差别的。



  • 相关阅读:
    RabbitMQ + PHP (二)AMQP拓展安装
    RabbitMQ + PHP (一)入门与安装
    使用 Selenium 实现基于 Web 的自动化测试
    Selenium私房菜系列4 -- Selenium IDE的使用
    解决火狐浏览器安装不上Selenium IDE插件“此附加组件无法安装”
    (技术分享) 解决 Firefox 显示“已阻止载入混合活动内容”的问题
    MyEclipse打开 HTML 报错Failed to create the part's controls
    python2x与python3x的区别
    Python基础总结
    Mycat 读写分离+分库分表
  • 原文地址:https://www.cnblogs.com/leolztang/p/5469506.html
Copyright © 2011-2022 走看看