关于移位和直接相乘的问题

java1109 2009-07-17 06:17:21
加精
int x = 1, y;
y = 0;
long time;
for(int k=0; k<8; k++) {
time = System.currentTimeMillis();
for(long j=0; j<2000000000; j++)
y = 2 * x;
System.out.println("所用时间1:" + (System.currentTimeMillis() - time));

time = System.currentTimeMillis();
for(long j=0; j<2000000000; j++)
y = x << 1;
System.out.println("所用时间2:" + (System.currentTimeMillis() - time));

System.out.println();
}

程序运行结果
所用时间1:10312
所用时间2:8782

所用时间1:9562
所用时间2:8734

所用时间1:10047
所用时间2:8766

所用时间1:10047
所用时间2:9078

所用时间1:9859
所用时间2:9141
int x = 1, y;
y = 0;
long time;
for(int k=0; k<8; k++) {
time = System.currentTimeMillis();
for(long j=0; j<2000000000; j++)
y = x << 1;
System.out.println("所用时间1:" + (System.currentTimeMillis() - time));

time = System.currentTimeMillis();
for(long j=0; j<2000000000; j++)
y = 2 * x;
System.out.println("所用时间2:" + (System.currentTimeMillis() - time));

System.out.println();
}

结果:
所用时间1:10000
所用时间2:8703

所用时间1:9188
所用时间2:8468

所用时间1:9969
所用时间2:9125

所用时间1:9891
所用时间2:8875

所用时间1:9906
所用时间2:9125

我想问下为什么放在后面的表达式所用的时间更短。
...全文
999 61 打赏 收藏 转发到动态 举报
写回复
用AI写文章
61 条回复
切换为时间正序
请发表友善的回复…
发表回复
天涯连海角 2010-12-02
  • 打赏
  • 举报
回复
整数乘法在编译器中都是通过移位实现的。比如计算十进制的100与十进制的2相乘(即二进制的1100100与二进制的10相乘),如果写成100*2就只用一次移位完成了,如果写成2*100则需要3次移位还有两次加法。
运算时是根据第二个操作数中的1位来对第一个操作数进行移位。因此,x*2比2*x要快。
laviewpbt 2009-07-21
  • 打赏
  • 举报
回复
呵呵
移位肯定要比乘法块吧
VB中的移位只能用乘法和右除来实现,不过我觉得乘法和右除也是很块的。
grs111 2009-07-20
  • 打赏
  • 举报
回复
呵呵,学习一下!!!
grs111 2009-07-20
  • 打赏
  • 举报
回复
呵呵,学习一下!!!
grs111 2009-07-20
  • 打赏
  • 举报
回复
呵呵,学习一下!!!
IniY0_0 2009-07-20
  • 打赏
  • 举报
回复
看看
luokaijie 2009-07-20
  • 打赏
  • 举报
回复
up
luokaijie 2009-07-20
  • 打赏
  • 举报
回复
up
fellatioyzx 2009-07-20
  • 打赏
  • 举报
回复
这个一定要学习了
chenql175 2009-07-20
  • 打赏
  • 举报
回复
受益匪浅啊,的确,按理说移位运算比乘法运算快的。如果没有其他线程的干扰的话
chenql175 2009-07-20
  • 打赏
  • 举报
回复
受益匪浅啊,的确,按理说移位运算比乘法运算快的。如果没有其他线程的干扰的话
chenql175 2009-07-20
  • 打赏
  • 举报
回复
受益匪浅啊,的确,按理说移位运算比乘法运算快的。如果没有其他线程的干扰的话
  • 打赏
  • 举报
回复
对于循环体比较简单的循环,时间大部分花在了循环控制上
PrinceSuperman 2009-07-20
  • 打赏
  • 举报
回复
我晕!! 还有这回事!
yoozo 2009-07-20
  • 打赏
  • 举报
回复
mark~~
ArayChou 2009-07-20
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 bigbug9002 的回复:]
4、for(long n=200000000;n>0;n--)这种结构的循环,在循环控制上花的时间,是与之相反的循环的近一半。
[/Quote]

我去详细研究了for(long n=200000000;n>0;n--)和for(long n=0; n<20000000000; n++)编译出来的东西的不同。

地一种写法的循环确实要快。来看看分析过程

先看普通的写法

package test;

public class Test {
public static void main(String[] args) {
for (int k =0; k<Integer.MAX_VALUE; k++)
;

}
}

反编译

public static void main(java.lang.String[]);
Code:
Stack=2, Locals=2, Args_size=1
0: iconst_0
1: istore_1
2: goto 8
5: iinc 1, 1
8: iload_1
9: ldc #16; //int 2147483647
11: if_icmplt 5
14: return
LineNumberTable:
line 5: 0
line 8: 14

LocalVariableTable:
Start Length Slot Name Signature
0 15 0 args [Ljava/lang/String;
2 12 1 k I


===============================================================

在看看这种写法

package test;

public class Test {
public static void main(String[] args) {
for (int k =Integer.MAX_VALUE; k>0; k--)
;

}
}

反编译

public static void main(java.lang.String[]);
Code:
Stack=1, Locals=2, Args_size=1
0: ldc #16; //int 2147483647
2: istore_1
3: goto 9
6: iinc 1, -1
9: iload_1
10: ifgt 6
13: return
LineNumberTable:
line 5: 0
line 8: 13

LocalVariableTable:
Start Length Slot Name Signature
0 14 0 args [Ljava/lang/String;
3 10 1 k I



注:我用的jdk是openJDK

下面只把循环体那出来看

//for (int k =0; k<Integer.MAX_VALUE; k++)
5: iinc 1, 1
8: iload_1
9: ldc #16; //int 2147483647
11: if_icmplt 5
//for (int k =Integer.MAX_VALUE; k>0; k--)
6: iinc 1, -1
9: iload_1
10: ifgt 6


差别有2个,最后一句一个是if_icmplt.一个是ifgt.还有就是上面一个多了一个ldc

我没查到资料一个指令到底需要多少cpu周期。而且在实际执行的时候,jvm会将指令转换为实际cpu指令,不同的硬件架构可能会不同。但是,我觉得有一点可以肯定。ifgt的周期不会大于if_icmplt. 而且ifgt只需要一个操作数。if_icmplt需要2个操作数。

for (int k =0; k<Integer.MAX_VALUE; k++)这种写法,多了一个ldc指令,它执行的时间肯定比较常。


总结:这2个写法的性能有差别,差别在于k>0和k<Integer.MAX_VALUE上面。



ed469 2009-07-19
  • 打赏
  • 举报
回复
问题高深
jayklx 2009-07-19
  • 打赏
  • 举报
回复
这个问题估计涉及到jvm的内部运行机制问题,可以去问sun~~
QQ7375791835353692 2009-07-19
  • 打赏
  • 举报
回复
.....
jyzxwjj 2009-07-19
  • 打赏
  • 举报
回复
太深奥了.
加载更多回复(41)

62,621

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧