回答
让我们找到它了:
void Test1() {
while (GetTickCount()) {
printf("Hello World Test1");
break;
}
}
void Test2() {
if (GetTickCount()) {
printf("Hello World Test2");
}
}
void main() {
Test1(); Test2();
}
编译使用VC 2013年11月CTP的释放与全面优化:
CPU Disasm
Address Hex dump Command Comments
012A12A0 /$ FF15 00302A01 CALL DWORD PTR DS:[<&KERNEL32.GetTickCou ; [KERNEL32.GetTickCount
012A12A6 |. 85C0 TEST EAX,EAX
012A12A8 |. 74 0E JZ SHORT 012A12B8
012A12AA |. 68 8C312A01 PUSH OFFSET 012A318C ; ASCII "Hello World Test1"
012A12AF |. FF15 64302A01 CALL DWORD PTR DS:[<&MSVCR120.printf>]
012A12B5 |. 83C4 04 ADD ESP,4
012A12B8 |> FF15 00302A01 CALL DWORD PTR DS:[<&KERNEL32.GetTickCou ; [KERNEL32.GetTickCount
012A12BE |. 85C0 TEST EAX,EAX
012A12C0 |. 74 0E JZ SHORT 012A12D0
012A12C2 |. 68 A0312A01 PUSH OFFSET 012A31A0 ; ASCII "Hello World Test2"
012A12C7 |. FF15 64302A01 CALL DWORD PTR DS:[<&MSVCR120.printf>]
012A12CD |. 83C4 04 ADD ESP,4
012A12D0 |> 33C0 XOR EAX,EAX
012A12D2 \. C3 RETN
正如你可以看到相同的代码由VC编译器生成。这虽然不是这种情况,如果禁止优化:
Test1的
CPU Disasm
Address Hex dump Command Comments
00F91630 /$ 55 PUSH EBP ; Playground.Test1(void)
00F91631 |. 8BEC MOV EBP,ESP
00F91633 |> FF15 0030F900 /CALL DWORD PTR DS:[<&KERNEL32.GetTickCo ; [KERNEL32.GetTickCount
00F91639 |. 85C0 |TEST EAX,EAX
00F9163B |. 74 12 |JZ SHORT 00F9164F
00F9163D |. 68 9C31F900 |PUSH OFFSET 00F9319C ; ASCII "Hello World Test1"
00F91642 |. FF15 6430F900 |CALL DWORD PTR DS:[<&MSVCR120.printf>]
00F91648 |. 83C4 04 |ADD ESP,4
00F9164B |. EB 02 |JMP SHORT 00F9164F
00F9164D |.^ EB E4 \JMP SHORT 00F91633
00F9164F |> 5D POP EBP
00F91650 \. C3 RETN
的Test2
CPU Disasm
Address Hex dump Command Comments
00F91660 /$ 55 PUSH EBP ; Playground.Test2(void)
00F91661 |. 8BEC MOV EBP,ESP
00F91663 |. FF15 0030F900 CALL DWORD PTR DS:[<&KERNEL32.GetTickCou ; [KERNEL32.GetTickCount
00F91669 |. 85C0 TEST EAX,EAX
00F9166B |. 74 0E JZ SHORT 00F9167B
00F9166D |. 68 B031F900 PUSH OFFSET 00F931B0 ; ASCII "Hello World Test2"
00F91672 |. FF15 6430F900 CALL DWORD PTR DS:[<&MSVCR120.printf>]
00F91678 |. 83C4 04 ADD ESP,4
00F9167B |> 5D POP EBP
00F9167C \. C3 RETN
正如你可以清楚地看到它们之间略有差别:
如果条件得不到满足,他们的行为完全一样的(从而以相同的速度执行)
如果条件满足,在
Test1
我们必须执行多一个跳跃(00F9164B
-JMP SHORT 00F9164F
)
=>Test2
从理论上讲,如果代码编译时没有进行优化,速度会更快,因为编译器会输出一个真实的循环,用于Test1
。
这是不成熟的优化吗? 绝对!
在汇编程序中输出代码并查看它是否与编译器相同(更有可能的是,编译器将对逻辑上相同的机器代码进行优化)。几乎总是编写可读和可维护的代码比担心诸如此类的细节更重要。随着现代编译器能够优化这种简单的情况,除了以最可读的方式编写代码之外,没有什么理由做任何事情了,在这种情况下,我认为将代码编写为if
语句表明您的意图向您的其他读者代码远远好于while
+ break
的组合。
逻辑上它们是相同的。编译器可能会写出相同的代码。
您应该专注于代码的清晰度,而不是考虑在昏迷的希望中编写混淆代码,以使代码更快。
while(x){
//stuff
break;
}
如果您只对给定条件执行一次操作,上面的代码似乎不合理。这就是为什么如果在这种情况下声明更可取!至于速度差异,我真的怀疑其中一个的重要优势。在地点的使用while循环的if语句是可怕的:
if(condition)
{
// do stuff
}
else if(another_condition)
{
// do stuff
}
else
{
// do stuff
}
这里是一个使用while循环等价的:
while(condition)
{
// do stuff
break;
}
while(!condition && another_condition)
{
// do stuff
break;
}
while(!condition && !another_condition)
{
// do stuff
break;
}
做你的团队一个忙,让你的代码可读性:-)
这是一样的。虽然在理论上,while()增加了一个jmp
比if if
为什么这样?这个额外的跳跃在哪里? –
@DavidHeffernan'break'后,如果编译器没有优化,它仍然需要跳转到条件。虽然它将永远不会被执行,因为'break' –
编译器只会在它是垃圾时才写出它。如果你关心性能,为什么你会使用不做优化的垃圾编译器? –
如果在第一次迭代中断开while循环,则while循环将充当if语句。
但是你不应该为此目的使用while循环,因为它的目的是循环。
因此,以下可能会给出相同的结果,因为for是被C预处理器修改为一段时间。尽管......其他人对清晰度的评价
for(;x;){
//stuff
break;
}
如果你没有回答这个问题,那么请把它作为评论。谢谢。 –
- 1. 突破到别的PHP
- 2. 区别,如果,如果(JAVA)
- 3. 如何“突破”dispatch_apply()?
- 4. 如何突破doseq?
- 5. 如何突破Cfoutput
- 6. 如何突破groovy'eachFileMatch()'
- 7. Firefox的过渡突破时
- 8. 如果和如果存在的区别
- 9. CSS如何突破线时长数据
- 10. 时区或时间冲突
- 11. GWT - 突破iframe
- 12. JSTL突破
- 13. jQuery突破表
- 14. HHVM突破NotFoundHttpException
- 15. 突破jQtouch?
- 16. 突破_.filter()
- 17. 将突破
- 18. 突破.each()
- 19. FooterWrap突破框
- 20. 如何突破$。每个
- 21. Sencha:如何突破Ext.each
- 22. 如何突破inner * ngFor?
- 23. 如何突破Java中
- 24. 如何突破功能?
- 25. 如何突破@providesModule缓存
- 26. AWS登录:Client.Timeout突破,同时等待头
- 27. 垂直对齐图像,同时突破容器
- 28. 泊坞窗错误在Windows 2016“Client.Timeout突破,同时等待头”
- 29. 从外环突破,同时通过内环
- 30. 如何同时突出显示地图上的多个区域
获取有关C++的入门书! – Nawaz
@Nawaz我想你无法在介绍性书籍 – Vider7CC
中发现我怀疑有人生气。如果你确实对此感兴趣,那么实际测量它并检查你自己是否真的没有想到这一点是令人惊讶的。或者阅读更多关于C++的内容。 – BartoszKP