注册 登录
编程论坛 C++教室

[讨论]for与goto 哪个的效率更高?

ioriliao 发布于 2007-06-19 10:01, 3103 次点击

#include <iostream>

using namespace std;

int main()
{
cout<<"The for run"<<endl;

double num1 = 0;
double num2 = 0;
cin >> num2;
for (num1; num1 < num2; num1 ++)
{
cout << " num1 = " << num1 <<endl;
}
cout << "END.."<<endl;
cin.get();
return 0;
}

#include <iostream>

using namespace std;

int main()
{
cout<<"The goto run"<<endl;
double num1 = 0;
double num2 = 0;
cin >> num2;
start:
if (++num1 >= num2)
{
goto end;
}
else
{
cout << " num1 = " << num1 <<endl;
goto start;
}
end:
cout << "END.."<<endl;
cin.get();
return 0;
}

执行同样的任务,这两具程序哪个会运行快些,如果存在,为什么,如果不存在又为什么?
32 回复
#2
doom52112007-06-19 12:55
第二个程序里的Num1的前置自加会不会影响运行效率啊?
#3
ioriliao2007-06-19 13:53
++num1 不会产生临时变量,我想是不会影响的.
#4
anthony6342007-06-19 13:55
无条件跳转吧,一般没人这么写,程序是先给人看再给机器看的
#5
doom52112007-06-19 15:50

我记得上程序设计课时老师引用过第杰思特拉的(Djstra)的一句话,大概是这么说的(因为记不清楚了,汗)"goto语句会给程序带来毁灭性的破坏".我想还是少用goto语句为好.

#6
yuyunliuhen2007-06-19 16:11
这个你也能拿来讨论,估计你是我见过的第一个
不过goto语句不常用,不是排斥,只是没必要的时候不会用这个
#7
ioriliao2007-06-19 17:25
呵呵...goto语句不提倡用,这个我是清楚得很的,但我讨论的不是应不应该用的问题.
#8
百年不亮2007-06-19 18:34
看汇编后的结果

汇编快成我在这里的口头禅了
#9
ioriliao2007-06-19 18:55
看来这些问题的研究得等我把C++学会应该怎么用再去翻汇编了.
以后不发这种贴了,还不够格...
#10
野比2007-06-19 19:50
你可以在程序开始输出一个当前时间(高精度)..
然后进行相同功能的运算..用两种方法.. 来他个几十万次循环...
最后结束时输出一个时间...

比较两个程序的耗时..
#11
ioriliao2007-06-19 19:53
要包含什么头文件用什么成员函数,谢谢!

[此贴子已经被作者于2007-6-19 19:56:55编辑过]


#12
野比2007-06-19 20:23
time.h

或者ctime.h (包含前者)
#13
anthony6342007-06-19 20:33
楼上的方法估计计算不出来对于这么小的玩意,最直接的方法就是反汇编看汇编程序,如果不要输出,goto应该就几行,for应该要10行左右

[此贴子已经被作者于2007-6-19 20:34:20编辑过]


#14
aipb20072007-06-19 20:49
在说什么?goto是不知道了,不过测试一程序时间我知道。
#15
野比2007-06-19 20:57
大侠, 你说啥呢? ..
汇编结果看行数就能看出效率吗?
汇编一句MUL需要几十个时钟周期, 一句INC只需要1个... 就算写10句还是比1句效率高..
这能说明问题吗?
更不要说还有JMP这些跳转了...效率不是看出来的, 是运行出来的..

循环10亿次简单乘法大概需要5秒的时间(Sempron 3000+, 1.6GHz/ 1GB RAM)
...5000毫秒, 足够看出差别了
#16
weishj2007-06-19 21:51

测试了1000000×100次c+=c*0.05后发现两种方法花费时间相同呢

#17
野比2007-06-19 22:55
我测试了1e10次... long=long * long
耗时..人工估计约5秒...
你的1e8次对于主频上GHz的CPU来说少了点...
我隐约记得有个函数可以以ms为单位输出过程运行时间...忘了是啥..(是不是C语言的都不太确定).
#18
孤魂居士2007-06-19 23:19

我运行了下
2个程序都是3.3秒 人工记时
我觉得斑竹还是蛮有创新精神的,没想到用GOTO语句都能做成循环出来``小弟佩服`
#19
野比2007-06-19 23:29
用clock()函数...
我运行了1e10次 long=long*long
结果耗时:
for循环 4736ms
goto 4547ms
..
over
#20
ioriliao2007-06-20 09:20
以下是引用anthony634在2007-6-19 13:55:34的发言:
无条件跳转吧,一般没人这么写,程序是先给人看再给机器看的

我的好像是有条件跳转

#21
ioriliao2007-06-20 09:22
以下是引用野比在2007-6-19 23:29:39的发言:
用clock()函数...
我运行了1e10次 long=long*long
结果耗时:
for循环 4736ms
goto 4547ms
..
over

差两秒有多,乍地会有这种差别的!

#22
anthony6342007-06-20 09:49


mov eax $0000000b
dec eax
jnz -$03


xor eax eax
cmp eax $0a
jnle +$0c
add eax $01
jno +$05
call @intover
jmp -$11
ret

[此贴子已经被作者于2007-6-20 12:41:20编辑过]

#23
ioriliao2007-06-20 09:55
在C++里看似是(其实我只是开个玩笑),变成汇编了我就不知道了....
#24
anthony6342007-06-20 09:57

一般使用goto都是为了追求速度,linux内核就有不少goto

#25
野比2007-06-20 19:49
以下是引用ioriliao在2007-6-20 9:22:28的发言:

差两秒有多,乍地会有这种差别的!

大锅... 1s=1000ms... NOT 100ms..
相差0.2秒左右...

#26
ioriliao2007-06-20 20:33
看错了....
#27
zcs3022007-06-20 22:45

个人认为效率应该是一样的
编译器会先转换成类似后者的语句再转换成汇编,然后就是机器了

#28
yz296312007-06-20 23:18
以下是引用野比在2007-6-19 20:57:18的发言:
大侠, 你说啥呢? ..
汇编结果看行数就能看出效率吗?
汇编一句MUL需要几十个时钟周期, 一句INC只需要1个... 就算写10句还是比1句效率高..
这能说明问题吗?
更不要说还有JMP这些跳转了...效率不是看出来的, 是运行出来的..

循环10亿次简单乘法大概需要5秒的时间(Sempron 3000+, 1.6GHz/ 1GB RAM)
...5000毫秒, 足够看出差别了

表示赞同

#29
herbert_19872007-06-23 13:06
看来goto的效率高一些.
#30
uestcbutcher2007-06-29 11:16
第一次来论坛.挺热闹的。
其实goto 和 for 好像没有什么可比性.goto 一般用来在两层或以上的循环嵌套中跳出是非常方便的.
我就经常用goto,如果控制的好的话,可以节约大量代码.
不过,就像一个函数最好只有一个出口一样,goto 会破坏其通路的唯一性.
#31
huozoo2007-06-29 19:58
别来几十万的循环啊```cpu崩溃!吓唬你```
#32
野比2007-06-29 22:00
几十万很正常, 前面讨论的都是上亿的循环...

-----------
今天看钱能的书, 他小子居然说"goto是造成程序混乱的罪魁祸首", 和"很容易引起逻辑错误"...
我靠... 这不是典型的"厨师笨, 怪刀钝"言论吗? ..
程序是人写的, 写的人蠢了, 再好的语句也没辙啊..
#33
weishj2007-06-30 13:07
歧视goto的人应该先歧视一下自己
我的意见是在程序员思路清晰的前提下,只要goto语句能为编程带来方便,就要灵活的使用.
在goto不能为编程带来方便的情况下,不要刻意使用.
比如在多层循环中实现大跳转,goto当然是首选.
但在类似以下程序段中用goto显然不爽
int i=0,j=0;
double c=0.05;
loop:
if(i++<1000000) //这是测试goto和for效率时我弄的用goto产生二重循环
loop2:
if(j++<100)
{
c+=c*0.05;
goto loop2;
}
else
{
j=0;
goto loop;
}
else goto end;
end:return 0;
这显然是没有下面的方便
for(i=0;i<1000000;i++)
for(j=0;j<100;j++)
c+=c*0.05;
1