这个问题更多的是性能问题,而不是优雅,我为自己说话,但是......
有两个实现选项,对于cpu来说计算速度更快,或者最后它是相同的(我倾向于认为是,因为条件是(x <10)相同)
public int DidLogcount = 0; // DidLogCount is raised by +1 every time we deside, then condition is met
public bool MoreLogsAllowed()
{
if (DidLogcount < 10) return true;
else return false;
}
VS
public bool MoreLogsAllowed()
{
return DidLogcount < 10;
}
我们大部分时间都会检查它是否为空,但是,如果我们必须这样做,它将包括两种情况,所以如果我没有错过任何其他问题,我猜它只是缩小了它(?)。
我会说出正确的答案。 THX。
重写: 我只想标记正确的答案,但在页面上刷新了3个以上......
等待更多选票......而现在,我真的要感谢你们所有人!为了分享你的知识,它确实经过了我的思考,编译器的优化问题,所以...有那些打印输出显示的东西,虽然它的自我很少差别,但当添加到一堆条件,它是少的很少,除非我们谈论一个真正复杂的应用程序,否则我不会说大。 我应该说,性能问题仍然是一个小问题,还有逻辑和可读性 感谢@Steve&amp; @Nick为我们实际测试它。
答案 0 :(得分:5)
我不确定是否会有任何性能差异,如果有的话,它可以忽略不计。但第二种情况更优雅。
答案 1 :(得分:4)
使用LinqPAD进行测试。
int DidLogcount = 5;
void Main()
{
MoreLogsAllowed();
MoreLogsAllowed2();
}
public bool MoreLogsAllowed()
{
if (DidLogcount < 10) return true;
else return false;
}
public bool MoreLogsAllowed2()
{
return (DidLogcount < 10);
}
并生成此IL代码
IL_0000: ldarg.0
IL_0001: call UserQuery.MoreLogsAllowed
IL_0006: pop
IL_0007: ldarg.0
IL_0008: call UserQuery.MoreLogsAllowed2
MoreLogsAllowed:
IL_0000: ldarg.0
IL_0001: ldfld UserQuery.DidLogcount
IL_0006: ldc.i4.s 0A
IL_0008: bge.s IL_000C
IL_000A: ldc.i4.1
IL_000B: ret
IL_000C: ldc.i4.0
IL_000D: ret
MoreLogsAllowed2:
IL_0000: ldarg.0
IL_0001: ldfld UserQuery.DidLogcount
IL_0006: ldc.i4.s 0A
IL_0008: clt
IL_000A: ret
第二个版本不仅更优雅,而且似乎产生更短的代码
为了确保这不是LinqPAD引入的差异,我使用Visual Studio 2010创建了一个小型控制台应用程序,并在发布模式下使用默认设置进行编译。
然后我使用ILDASM来查看IL colde
我确认上面的代码与编译器生成的代码相同
当然差异可以忽略不计,但这两个版本不会产生相同的IL代码。
答案 2 :(得分:2)
对于我来说,第一个例子没有优雅。此外,我认为编译器将优化第一种情况,因此没有什么可谈的性能。对我来说,第二个例子更简洁,更简洁,更易读。
答案 3 :(得分:2)
如果两种替代方案之间的性能存在差异,我会感到非常惊讶。我也发现第二种选择更优雅,我甚至会省略括号。
然而,对于更复杂的条件,特别是如果涉及函数调用,在不同的行上使用两个return语句可以更方便地找到在使用调试器单步执行代码时发生的事情。
答案 4 :(得分:2)
任何性能差异都可能是微不足道的,并且高度依赖于.NET JIT编译 - 但是看一下x86示例,比较结果如下:
if (DidLogcount < 10) return true;
... skipped DidLogCount call...
00000020 mov dword ptr [ebp-4],eax
00000023 cmp dword ptr [ebp-4],0Ah
00000027 jge 00000037
00000029 mov eax,1
0000002e and eax,0FFh
00000033 mov esp,ebp
00000035 pop ebp
00000036 ret
else return false;
00000037 xor eax,eax
00000039 mov esp,ebp
0000003b pop ebp
0000003c ret
VS
return (DidLogcount < 10);
... skipped DidLogCount call...
0000001f mov dword ptr [ebp-4],eax
00000022 cmp dword ptr [ebp-4],0Ah
00000026 setl al
00000029 movzx eax,al
0000002c mov esp,ebp
0000002e pop ebp
0000002f ret
后者可能会更快 - 但同样取决于你的CPU如何处理这些指令。
最好的答案是编写测试应用程序来测量它!
答案 5 :(得分:0)
两个片段之间没有区别,因为最重要的是MSIL,在编译之后,在这种情况下,编译的代码是相同的。
Code 1 C# -> MSIL 1 -> Code natif 1
Code 2 C# -> MSIL 1 -> Code natif 1