`

x=x+1,x+=1,x++效率比较

阅读更多

  最近在做java性能优化的总结,给部门同学分享,在网上看到帖子说到x=x+1,x+=1,x++效率比较,分析了

三种方式的效率,觉得似乎有些道理,一般的结论如下:

 


x=x+1效率最低:
<1>取右x地址
<2>执行x+1得到右值存放到临时变量
<3>取左x地址
<4>将右值传给左x(编译器并不认为左右x地址相同)

其次是x+=1:
<1>取右x地址
<2>执行x+1存放到临时变量
<3>将得到的值传给x(因为x的地址已经读出)

最快的是x++:
<1>取右x地址
<2>x自增1
 于是我把总结的帖子发表了,今天进行demo编写测试发现结果却并非如此:
代码如下:
import java.util.ArrayList;

/**
 * 
* <P>Tiltle: TestXPlus.java </P>
* <P>Description: 测试i=i+1,i+=1,i++的效率 </P>
* @author biyutong
* @date Mar 10, 2012 8:09:52 PM 
* @version:V1.0
 */
public class TestXPlus {

	/** 
	 * <P>Title: main </P>
	 * <P>Description:测试i=i+1,i+=1,i++的效率 </P>
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		long s1 = System.currentTimeMillis();
		Runtime.getRuntime().gc();
		long startMem1 = Runtime.getRuntime().freeMemory();
		System.out.println("开始内存剩余量"+startMem1);
		int x=0;
		for(int i=0;i<2000000000;i++){
			//测试1
			x=x+1;
			//测试2
			//x+=1;
			//测试3
			//x++;
		}
		
		
		
		long s2 = System.currentTimeMillis();
		long startMem2 = Runtime.getRuntime().freeMemory();
		System.out.println("用时: "+(s2-s1)+"毫秒");
		System.out.println("结束时剩余内存: "+startMem2);
		System.out.println("内存使用量: "+(startMem1-startMem2));
		ArrayList<String> test = new  ArrayList<String>();
	}

}
 三个测试结果为:
 写道
//测试1
/*
*开始内存剩余量5036728
*用时: 1450毫秒
*结束时剩余内存: 5018352
*内存使用量: 18376
*/

/*测试2
*开始内存剩余量5036728
*用时: 1450毫秒
*结束时剩余内存: 5018352
*内存使用量: 18376

/*


/*测试3
* 开始内存剩余量5036728
用时: 1449毫秒
结束时剩余内存: 5018352
内存使用量: 18376

*/
 感到有些困惑,后来通过查看论坛上的帖子,觉得可能原因是在java进行编译的时候,最终的指令是一样 的,在运行时就不会有差别了。
  在此,引以为戒,不能盲目看结论,实践出真知。

 

 

3
1
分享到:
评论
6 楼 sd543521 2012-03-11  
canghailan 写道
你这么测试误差太大了。中间有gc(),System.out.println(),这些才是耗时操作。
即使你把时间记录放在循环开始和结束,也是测不准的。
引用

for(int i=0;i<2000000000;i++){  
	//测试1  
	x=x+1;  
	//测试2  
	//x+=1;  
	//测试3  
	//x++;  
}


这个循环的时间才是主要的,你要测试的操作消耗的时间很难测准确。

其实你看一下编译出来的字节码就知道了。
public class Test {
	public static void main(String[] args) {
		int x = 0;
		test1(x);
		test2(x);
		test3(x);
	}
	
	public static int test1(int x) {
		x = x + 1;
		return x;
	}
	
	public static int test2(int x) {
		x += 1;
		return x;
	}
	
	public static int test3(int x) {
		x++;
		return x;
	}
}

javac Test.java
javap -c Test.class
Compiled from "Test.java"
public class Test {
  public Test();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":
()V
       4: return

  public static void main(java.lang.String[]);
    Code:
       0: iconst_0
       1: istore_1
       2: iload_1
       3: invokestatic  #2                  // Method test1:(I)I
       6: pop
       7: iload_1
       8: invokestatic  #3                  // Method test2:(I)I
      11: pop
      12: iload_1
      13: invokestatic  #4                  // Method test3:(I)I
      16: pop
      17: return

  public static int test1(int);
    Code:
       0: iload_0
       1: iconst_1
       2: iadd
       3: istore_0
       4: iload_0
       5: ireturn

  public static int test2(int);
    Code:
       0: iinc          0, 1
       3: iload_0
       4: ireturn

  public static int test3(int);
    Code:
       0: iinc          0, 1
       3: iload_0
       4: ireturn
}

可以看出
x = x + 1;
编译后为:
       0: iload_0
       1: iconst_1
       2: iadd
       3: istore_0
x += 1;与x++
编译后为:
       0: iinc          0, 1

其实本来是要这样测试的,但是考虑到后台执行程序会有内存消耗,所以加上了gc,谢谢提醒
5 楼 sd543521 2012-03-11  
canghailan 写道
这三种写法都不会成为系统的性能瓶颈,所有你作优化时不需要考虑这个。反而应该考虑那种写法在上下文中更加清晰,这三种写法的可读性更值得关注。

嗯,是的,从实验来看,基本上没有差别的,以后不会太多考虑这个的。O(∩_∩)O谢谢啦
4 楼 sd543521 2012-03-11  
kanme818 写道
我觉得,在这些上面抠性能还真心不如在流程上抠性能呢,多写一个无用的循环要抠多少个这个啊。
还有就是业务逻辑上抠性能。

是的,目前我们最主要的性能优化还是在db和业务逻辑上,我是在网上看到这个相关的内容进行了测试,之前倒是也没考虑过这个的
3 楼 kanme818 2012-03-11  
我觉得,在这些上面抠性能还真心不如在流程上抠性能呢,多写一个无用的循环要抠多少个这个啊。
还有就是业务逻辑上抠性能。
2 楼 canghailan 2012-03-11  
这三种写法都不会成为系统的性能瓶颈,所有你作优化时不需要考虑这个。反而应该考虑那种写法在上下文中更加清晰,这三种写法的可读性更值得关注。
1 楼 canghailan 2012-03-11  
你这么测试误差太大了。中间有gc(),System.out.println(),这些才是耗时操作。
即使你把时间记录放在循环开始和结束,也是测不准的。
引用

for(int i=0;i<2000000000;i++){  
	//测试1  
	x=x+1;  
	//测试2  
	//x+=1;  
	//测试3  
	//x++;  
}


这个循环的时间才是主要的,你要测试的操作消耗的时间很难测准确。

其实你看一下编译出来的字节码就知道了。
public class Test {
	public static void main(String[] args) {
		int x = 0;
		test1(x);
		test2(x);
		test3(x);
	}
	
	public static int test1(int x) {
		x = x + 1;
		return x;
	}
	
	public static int test2(int x) {
		x += 1;
		return x;
	}
	
	public static int test3(int x) {
		x++;
		return x;
	}
}

javac Test.java
javap -c Test.class
Compiled from "Test.java"
public class Test {
  public Test();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":
()V
       4: return

  public static void main(java.lang.String[]);
    Code:
       0: iconst_0
       1: istore_1
       2: iload_1
       3: invokestatic  #2                  // Method test1:(I)I
       6: pop
       7: iload_1
       8: invokestatic  #3                  // Method test2:(I)I
      11: pop
      12: iload_1
      13: invokestatic  #4                  // Method test3:(I)I
      16: pop
      17: return

  public static int test1(int);
    Code:
       0: iload_0
       1: iconst_1
       2: iadd
       3: istore_0
       4: iload_0
       5: ireturn

  public static int test2(int);
    Code:
       0: iinc          0, 1
       3: iload_0
       4: ireturn

  public static int test3(int);
    Code:
       0: iinc          0, 1
       3: iload_0
       4: ireturn
}

可以看出
x = x + 1;
编译后为:
       0: iload_0
       1: iconst_1
       2: iadd
       3: istore_0
x += 1;与x++
编译后为:
       0: iinc          0, 1

相关推荐

    excel用图表动态反映数学函数y=3x+4的曲线.docx

    XY 散点图是一种常用的图表类型,通常用于比较跨类别的聚合数据,处理值的分布和数据点的分簇。它特别适合于科学数据、统计数据和工程数据的可视化。 知识点二:Excel 中的绝对引用 在 Excel 中,使用绝对引用可以...

    一元多项式运算数据结构课设.zip

    设有一元多项式Am(x)和Bn(x),Am(x)=A0+A1x1+A2x2+A3x3+… +Amxm,Bn(x)=B0+B1x1+B2x2+B3x3+… +Bnxn,请实现求M(x)= Am(x)+Bn(x)、M(x)= Am(x)-Bn(x)和M(x)= Am(x)×Bn(x)。 分别采用顺序和链式存储结构实现;结果...

    x=x 1,x =1,x 的效率哪个最高?

    本文将深入探讨“x=x+1”,“x=1”,以及“x++”这三种赋值操作在不同编程语言中的效率差异。 首先,让我们来看一下“x=x+1”这个表达式。在某些编程语言中,这个操作可能并不像看起来那么简单。它实际上包含了四个...

    数学建模优化问题经典练习.pdf

    x41 + x42 + x43 + x44 = 1 x11 + x21 + x31 + x41 = 1 x12 + x22 + x32 + x42 = 1 x13 + x23 + x33 + x43 = 1 x14 + x24 + x34 + x44 = 1 其中,xij表示工人i完成工作j的时间。 解决方法:使用整数规划算法,可以...

    H264 RTP负载格式中文说明 —— H264 RTP Payload Format

    通过单一NAL单元模式、组合封包模式以及分片封包模式的选择和应用,可以有效地提高视频传输的效率和质量,同时减少带宽消耗。此外,熟悉NALU头结构及RTP头结构有助于更好地理解视频流传输的过程和技术细节。

    量程计算器 y=kx+b

    用户输入原始的4-20mA值,程序将自动计算出对应的温度或ppm值,极大地提高了工作效率和精度。 总的来说,量程计算是工程中不可或缺的部分,通过理解比例系数和偏移量的概念,我们可以有效地进行不同量程之间的转换...

    应用牛顿法求方程cos(x)cosh(x)-1=0的头五个非零的正根

    \[ x_{n+1} = x_n - \frac{f(x_n)}{f'(x_n)} \] 其中,`f(x)` 是待求解的方程,`f'(x)` 是方程的导数。 3. **停止条件**:通常设置一个迭代次数上限或判断相邻两次迭代的差值是否小于预设的精度阈值。 在MATLAB中...

    循环冗余校验CRC的算法分析和程序实现.doc

    - **CRC-32**:广泛应用于网络通信,如Ethernet和MPEG解码芯片中,生成多项式为`g(x) = x^32 + x^26 + x^23 + x^22 + x^16 + x^12 + x^11 + x^10 + x^8 + x^7 + x^5 + x^4 + x^2 + x + 1`。 #### 四、CRC的编码与...

    一元多项式

    一元多项式是数学中的基础概念,指的是形如f(x) = a_nx^n + a_{n-1}x^{n-1} + ... + a_1x + a_0的函数,其中a_i为系数,x为变量,n为非负整数。在计算机科学中,一元多项式通常被用来表示和处理各种计算问题,例如在...

    常用积分表(绝对有帮助)[归类].pdf

    4. ∫(ax+b)^n dx = (ax+b)^(n+1) / (n+1)a + C 二、含有axb+的积分 10. ∫dx / (ax+b) = (1/a) ln|ax+b| + C 11. ∫x dx / (ax+b) = (x/a) - (b/a) ln|ax+b| + C 12. ∫x^2 dx / (ax+b) = (x^2/a) - (2bx/a) ln|...

    C语言编程跳水高手.doc

    x = (B == 2) * (A == 3) + (B == 2) * (E == 4) + (C == 1) * (D == 2) + (C == 5) * (D == 3) + (E == 4) * (A == 1); y = (B == 2) + (A == 3) + (B == 2) + (E == 4) + (C == 1) + (D == 2) + (C == 5) + (D =...

    因式分解法解一元二次方程课件PPT学习教案.pptx

    课件通过具体例子,如x²-4=0,(x+1)²-25=0,展示了如何运用因式分解法解一元二次方程。例如,x²-4=(x+2)(x-2)=0,可得x=2或x=-2。 此外,课件还包含了一些例题,如x(x-2)+x-2=0,通过合并同类项、移项,再因式...

    灵活应用C语言中的 /--运算符.pdf

    灵活应用C语言中的++/--运算符 C语言中的++/--运算符是编程中非常重要的一部分,但是它的使用过于灵活多变,不易掌握。因此,本文将结合实例归纳了++/--运算符在...这样才能更好地掌握++/--运算符,并提高编程的效率。

    用C语言编程:用公式计算:e≈1+1/1!+1/2! …+1/n!,精度为10-6

    初始值`y`设为1,然后通过循环将`i`从1累加到`x`,每次都将`i`乘以`y`,从而得到阶乘结果。 #### 3.3 输出结果 最后,通过`printf`函数输出计算得到的`e`的近似值。 ### 4. 编程技巧与注意事项 - **循环结构**:...

    生成圆弧的Bresenham算法.doc

    与中点画线法一样,构造判别式:d = F(M) = F(xp+1, yp-0.5) = (xp+1)^2 + (yp-0.5)^2 - R^2 如果 d ,则应取 P1 为下一个象素,判别式为:d = F(xp+2, yp-0.5) = (xp+2)^2 + (yp-0.5)^2 - R^2 = d + 2xp + 3 如果...

    求点关于直线对称点坐标的一种简便方法

    **例4**:设函数 \(f(x) = -x^3 + 3x + 2\) 分别在 \(x_1, x_2\) 处取得极小值和极大值,点 \(A\)、\(B\) 的坐标分别为 \((x_1, f(x_1))\)、\((x_2, f(x_2))\)。动点 \(P\) 满足特定条件,求动点 \(Q\)(点 \(P\) ...

    一元多项式乘法课设

    执行结果应该与预期相符,能够展示算法的正确性和效率。 总的来说,这个一元多项式乘法课设是一个全面的编程实践,涵盖了从需求分析到系统实现的全过程,对提升编程技能和算法理解非常有帮助。通过这个项目,学生...

    道路坐标计算程序

    《道路坐标计算程序详解》 在道路施工测量中,计算坐标是一项至关重要的任务,它涉及到道路设计、施工放样以及后期的精度...理解并掌握这些计算方法,对于道路工程技术人员来说,无疑是提升工作效率和工程质量的关键。

    中点画线法matlab代码

    - **MATLAB语法**:MATLAB中的自增运算符与C语言不同,应使用`x = x + 1`而非`x++`。 - **控制结构**:`if-end`, `while-end`, `for-end`, `switch-end`等控制结构必须一一对应配对。 - **注释**:MATLAB中注释以`%`...

    100个经典c语言例题带答案.doc

    【C语言经典编程题目解析】 在C语言的学习过程中,经典的编程练习题可以帮助我们更好地理解和掌握C语言的基础知识,包括变量、循环、条件判断等。...同时,它们也体现了C语言在解决实际问题中的灵活性和效率。

Global site tag (gtag.js) - Google Analytics