以下两段代码之间是否存在性能差异?
if (myCondition)
{
return "returnVal1";
}
return "returnVal2"
和
if (myCondition)
{
return "returnVal1";
}
else
{
return "returnVal2";
}
我的直觉是编译器应该对此进行优化,并且应该没有区别,但我经常看到它在我们的代码中完成了两种方式。我想知道它是否归结为偏好和可读性。
答案 0 :(得分:13)
我很确定编译器会优化它。为您做最具可读性/遵循惯例的事情,并让编译器处理类似的简单事情。
即使没有进行优化,性能差异也可以忽略不计。
答案 1 :(得分:12)
找出答案的最佳方法是查看代码!这是VS2005 C#在发布模式下生成的代码:
static bool F1 (int condition)
{
if (condition > 100)
00000000 push ebp
00000001 mov ebp,esp
00000003 push eax
00000004 mov dword ptr [ebp-4],ecx
00000007 cmp dword ptr ds:[009185C8h],0
0000000e je 00000015
00000010 call 79469149
00000015 cmp dword ptr [ebp-4],64h
00000019 jle 00000024
{
return true;
0000001b mov eax,1
00000020 mov esp,ebp
00000022 pop ebp
00000023 ret
}
return false;
00000024 xor eax,eax
00000026 mov esp,ebp
00000028 pop ebp
00000029 ret
}
static bool F2 (int condition)
{
if (condition > 100)
00000000 push ebp
00000001 mov ebp,esp
00000003 push eax
00000004 mov dword ptr [ebp-4],ecx
00000007 cmp dword ptr ds:[009185C8h],0
0000000e je 00000015
00000010 call 79469109
00000015 cmp dword ptr [ebp-4],64h
00000019 jle 00000024
{
return true;
0000001b mov eax,1
00000020 mov esp,ebp
00000022 pop ebp
00000023 ret
}
else
{
return false;
00000024 xor eax,eax
00000026 mov esp,ebp
00000028 pop ebp
00000029 ret
}
这表明两个版本生成完全相同的代码,正如您所希望的那样。我还尝试了第三种选择:
static bool F3 (int condition)
{
return condition > 100;
00000000 push ebp
00000001 mov ebp,esp
00000003 push eax
00000004 mov dword ptr [ebp-4],ecx
00000007 cmp dword ptr ds:[009185C8h],0
0000000e je 00000015
00000010 call 794690C9
00000015 cmp dword ptr [ebp-4],64h
00000019 setg al
0000001c movzx eax,al
0000001f mov esp,ebp
00000021 pop ebp
00000022 ret
}
效率更高,因为它永远不会分支(分支通常很糟糕!)。
修改
实际上,找出哪个更有效的最好方法是分析代码,而不是查看汇编程序。
此外,它生成的代码非常不寻常。 push eax / mov [],ecx位是相同的,当然,作为单推ecx。此外,它通过寄存器传递然后将值存储在堆栈上。我想知道在调试器中运行代码来查看汇编程序是否正在改变代码的生成方式。
答案 2 :(得分:5)
虽然优化是一件好事,但可读性也很重要,所以如果你认为有助于提高可读性,那么它比你节省的纳秒更好。 IMHO
答案 3 :(得分:4)
如果您的编译器没有将它优化为相同的字节码,请将其抛出窗口!
答案 4 :(得分:2)
如果性能受到影响并且代码表明没有。
,我会非常惊讶经过多年尝试找出遗留代码,其中多个编码器试图在编辑器中优化表达式并产生了令人难以理解的难以理解的代码,我只能说你应该写出有意义的东西并表达你想要的东西。最简单,最清晰的方式。
所有代码片段都很容易理解,因为它们很小但是想象逻辑分散在几页......
答案 5 :(得分:1)
答案 6 :(得分:0)
关于这个问题,除非你总是评估的案例是else条款,否则它不会有性能问题。
如评论中所述,您应该返回myCondition。但是,为了便于阅读,您应始终包含else子句。如果其他什么都不做,那么请说明:
//do nothing
它帮助开发人员在编写代码之后查看代码,以了解其他情况,但是没有存在的情况。这也是一个记录为什么没有其他的好地方。
性能受到影响的示例如下:
int x = 2;
if x != 2 {
return true;
} else {
return false;
}
它将始终检查if子句失败,因此必须检查else子句。
编辑:如果else子句什么都不做,编译器将跳过它 - 它只是为了阅读其他开发人员的目的而派上用场。它还可以使您的代码更简洁:
if(x=2) {
doThis();
}
if(x!=2){
doThat();
}
可能会让人感到困惑,很容易合并到:
if(x==2){
doThis();
} else {
doThat();
}
答案 7 :(得分:0)
此外,最佳做法是拥有一条返回路径,而不是多条返回路径。
if (myCondition)
{ return true;}
else
{ return false;}
应该是:
bool myResult = false;
if (myCondition)
myResult = true;
return myResult;
当你开始在同一个方法中引入多个返回路径时,即使是简单的方法,也会使调试成倍地复杂化。
至于哪个是“更好”,我相信编译器处理两者(使用和不使用else),因为else是单个语句。