ake*_*ent 63
简答:不,他们完全一样.
猜测它理论上可能依赖于编译器; 一个真正破碎的人可能会做一些略有不同的事情,但我会感到惊讶.
只是为了好玩,这里有两个变体,使用Ubuntu附带的x86 gcc版本4.3.3编译为完全相同的汇编代码.您可以使用linux 上的objdump检查最终二进制文件上生成的程序集.
int main()
{
#if 1
int i = 10;
do { printf("%d\n", i); } while(--i);
#else
int i = 10;
for (; i; --i) printf("%d\n", i);
#endif
}
编辑:这是一个"橘子与橘子",而循环示例也编译成同样的东西:
while(i) { printf("%d\n", i); --i; }
Pau*_*lin 14
如果for和while循环执行相同的操作,编译器生成的机器代码应该(几乎)相同.
比如几年前我做的一些测试,
for (int i = 0; i < 10; i++)
{
...
}
Run Code Online (Sandbox Code Playgroud)
和
int i = 0;
do
{
...
i++;
}
while (i < 10);
Run Code Online (Sandbox Code Playgroud)
将生成完全相同的代码,或者(和Neil在评论中指出)使用一个额外的jmp,这将无法在性能上产生足够大的差异而担心.
没有语义差异,不需要任何编译差异.但这取决于编译器.所以我尝试使用g ++ 4.3.2,CC 5.5和xlc6.
g ++,CC是相同的,xlc不是
xlc的差异在于初始循环条目.
extern int doit( int );
void loop1( ) {
for ( int ii = 0; ii < 10; ii++ ) {
doit( ii );
}
}
void loop2() {
int ii = 0;
while ( ii < 10 ) {
doit( ii );
ii++;
}
}
Run Code Online (Sandbox Code Playgroud)
XLC输出
.loop2: # 0x00000000 (H.10.NO_SYMBOL)
mfspr r0,LR
stu SP,-80(SP)
st r0,88(SP)
cal r3,0(r0)
st r3,64(SP)
l r3,64(SP) ### DIFFERENCE ###
cmpi 0,r3,10
bc BO_IF_NOT,CR0_LT,__L40
...
enter code here
.loop1: # 0x0000006c (H.10.NO_SYMBOL+0x6c)
mfspr r0,LR
stu SP,-80(SP)
st r0,88(SP)
cal r3,0(r0)
cmpi 0,r3,10 ### DIFFERENCE ###
st r3,64(SP)
bc BO_IF_NOT,CR0_LT,__La8
...
Run Code Online (Sandbox Code Playgroud)
while循环测试中变量的范围比for循环标题中声明的变量范围更宽.
因此,如果存在性能影响作为保持变量更长时间活动的副作用,那么在while和for循环之间进行选择会产生性能影响(并且不会在{}中包含while,以缩小其范围.变量).
一个示例可能是并发集合,它计算引用它的迭代器的数量,如果存在多个迭代器,它会应用锁定以防止并发修改,但如果只有一个迭代器引用它,优化就会使锁定失败.如果你for在一个函数中有两个循环,在同一个容器上使用不同名称的迭代器,则会采用快速路径,但是如果有两个while循环,则会采用慢速路径.同样,如果对象很大(更多缓存流量)或使用系统资源,可能会影响性能.但我想不出一个我见过的真正的例子,它会产生什么影响.
两者都是等价的.这是一个语义问题.
唯一的区别可能在于做... while结构,在那里你推迟条件的评估,直到之后的身体,从而可节省1分的评价.
i = 1; do { ... i--; } while( i > 0 );
Run Code Online (Sandbox Code Playgroud)
而不是
for( i = 1; i > 0; --i )
{ ....
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2847 次 |
| 最近记录: |