关于for循环效率的问题

小乖214 2011-11-28 11:42:21
那位大神能帮忙解释一下
一般都是外层循环小内层循环大的效率会比外层大内层小快,但是如果用一个循环为什么会比用两个循环慢呢,而且会慢很多
import java.util.Date;
public class sssfda {
public static void main(String[] args) {
long i;
long time1=System.nanoTime();
for (i = 0; i < 1000000000; i++) {
}
long time2=System.nanoTime();
System.out.println(i);
System.out.println(time2-time1);

long k = 0;
long time3=System.nanoTime();
for (int o = 0; o < 10000000; o++) {
for (int b = 0; b < 100; b++) {
k = k + 1;
}
}
long time4=System.nanoTime();
System.out.println(k);
System.out.println(time4-time3);

long f = 0;
long time5=System.nanoTime();
for (int o = 0; o < 100; o++) {
for (int b = 0; b < 10000000; b++) {
f = f + 1;
}
}
long time6=System.nanoTime();
System.out.println(f);
System.out.println(time6-time5);
}
}

1000000000
3743415992
1000000000
1709059112
1000000000
1564084821

...全文
327 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
qybao 2011-11-28
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 gaowenyue 的回复:]
你说的第一点 我可以多试几次取个平均值 大体上的时间消耗都是一样的

第二个回复 我的int都是调用了1000000000次 而long也是自加了1000000000次 调用次数都是一样的啊
[/Quote]
你没明白我的第二个回复
你用
javap -verbose sssfda
反编译看看相应的指令就知道了
你的int总共也是1000000000次,但是o<100和b<10000000的比较是int类型的比较,调用if_icmpge指令做比较,而i<1000000000是long类型的比较,调用lcmp指令比较,从这些数据来看,估计是lcmp指令比if_icmpge指令慢,你把你的小循环int o和int b改成long o和long b试试看就知道了
tianmaxingkong139 2011-11-28
  • 打赏
  • 举报
回复
这问题都能被楼主发现,厉害
小乖214 2011-11-28
  • 打赏
  • 举报
回复
你说的第一点 我可以多试几次取个平均值 大体上的时间消耗都是一样的

第二个回复 我的int都是调用了1000000000次 而long也是自加了1000000000次 调用次数都是一样的啊
qybao 2011-11-28
  • 打赏
  • 举报
回复
反编译调查了一下,估计是int和long的比较指令不同造成的
int的比较是调用if_icmpge指令
而long的比较是调用lcmp指令
不同的指令耗时也不一定相同,估计lcmp更耗时,所以直接用大循环因为是long比较,所以慢
如果LZ想了解更多,可以自己搜索一下,找找看两个指令的比较有什么不同
qybao 2011-11-28
  • 打赏
  • 举报
回复
程序执行的CPU时间不一定是连续的,比如第一个循环的时候,途中CPU被1度收回去做执行其他处理,然后再分配给程序继续执行,而第二个循环的时候程序一直占用CPU,这样,就造成时间分配可能有差别,所以一次执行结果不能体现问题,你再把两种循环的顺序调个位置,然后多次循环看看,再比较结果
jingluo 2011-11-28
  • 打赏
  • 举报
回复
我看阿宝的解释很靠谱啊,有用!
楼主把后面两循环变量也换成long的,看结果这样么?
quhuafeng521 2011-11-28
  • 打赏
  • 举报
回复
我猜:。。这会不是会是跟计算机的运算有关啊。
内大外小循环总是在反复调用一个指令很少进行切换。而外层大。内层小需要不断的切换运算指令。。。。
龙四 2011-11-28
  • 打赏
  • 举报
回复
我记得在IBM J9 1.5上测试过一个例子,外层循环是大循环,内层循环小循环比内大外小的更快
小乖214 2011-11-28
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 qybao 的回复:]
引用 6 楼 gaowenyue 的回复:
引用 5 楼 qybao 的回复:
引用 3 楼 gaowenyue 的回复:
你说的第一点 我可以多试几次取个平均值 大体上的时间消耗都是一样的

第二个回复 我的int都是调用了1000000000次 而long也是自加了1000000000次 调用次数都是一样的啊

你没明白我的第二个回复
你用
javap -verbose ss……
[/Quote]

不好意思 没注意到 嘿嘿
qybao 2011-11-28
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 gaowenyue 的回复:]
引用 5 楼 qybao 的回复:
引用 3 楼 gaowenyue 的回复:
你说的第一点 我可以多试几次取个平均值 大体上的时间消耗都是一样的

第二个回复 我的int都是调用了1000000000次 而long也是自加了1000000000次 调用次数都是一样的啊

你没明白我的第二个回复
你用
javap -verbose sssfda
反编译看看相应的指令就知道了
你……
[/Quote]
这不是由你觉得,计算机对不同类型的处理不同,这是很正常的
for (long o = 0; o < 10000000; o++) {
for (int b = 0; b < 100; b++) {
你这里的int b还是int的,所以还是比一个循环的long快

小乖214 2011-11-28
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 qybao 的回复:]
引用 3 楼 gaowenyue 的回复:
你说的第一点 我可以多试几次取个平均值 大体上的时间消耗都是一样的

第二个回复 我的int都是调用了1000000000次 而long也是自加了1000000000次 调用次数都是一样的啊

你没明白我的第二个回复
你用
javap -verbose sssfda
反编译看看相应的指令就知道了
你的int总共也是1000000000次……
[/Quote]

public static void main(String[] args) {
long i;
long time1=System.nanoTime();
for (i = 0; i < 1000000000; i++) {
}
long time2=System.nanoTime();
System.out.println(i);
System.out.println(time2-time1);

long k = 0;
long time3=System.nanoTime();
for (long o = 0; o < 10000000; o++) {
for (int b = 0; b < 100; b++) {
k = k + 1;
}
}
long time4=System.nanoTime();
System.out.println(k);
System.out.println(time4-time3);

long f = 0;
long time5=System.nanoTime();
for (long o = 0; o < 100; o++) {
for (long b = 0; b < 10000000; b++) {
f = f + 1;
}
}
long time6=System.nanoTime();
System.out.println(f);
System.out.println(time6-time5);
}

1000000000
3820805997
1000000000
1750685632
1000000000
3760425138

我总是觉得用一个for循环会比较节省时间啊 用两个for循环会各种浪费资源啊

62,614

社区成员

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

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