我们在工作中讨论了代码设计,其中一个问题是在处理对布尔方法的调用时的响应,如下所示:
bool ok = IsEverythingOK();
if(ok)
{
//do somehthing
}
Run Code Online (Sandbox Code Playgroud)
我的一位同事坚持认为我们跳过额外的变量ok并写
if(IsEverythingOK())
{
//do somehthing
}
Run Code Online (Sandbox Code Playgroud)
因为他说使用"bool ok" - 陈述是记忆性不好的.
我们应该使用哪一个?
解释你的问题:
使用局部变量是否有成本?
因为C#和.NET设计得很好,我的期望是使用你描述的局部变量没有或可忽略不计的成本,但让我尝试用一些事实来支持这个期望.
以下C#代码
if (IsEverythingOk()) {
...
}
Run Code Online (Sandbox Code Playgroud)
将编译成这个(简化的)IL(打开优化)
call IsEverythingOk
brfalse.s AfterIfBody
... if body
Run Code Online (Sandbox Code Playgroud)
使用局部变量
var ok = IsEverythingOk();
if (ok) {
...
}
Run Code Online (Sandbox Code Playgroud)
你得到这个优化(和简化)IL:
call IsEverythingOk
stloc.0
ldloc.0
brfalse.s AfterIfBody
... if body
Run Code Online (Sandbox Code Playgroud)
从表面上看,这似乎效率稍低,因为返回值存储在堆栈上然后重新执行,但JIT编译器也会执行一些优化.
您可以通过调试应用程序并启用本机代码调试来查看生成的实际机器代码.您必须使用发布版本执行此操作,并且还必须关闭调试器选项,该选项会阻止对模块加载的JIT优化.现在,您可以在要检查的代码中放置断点,然后查看反汇编.请注意,JIT就像一个黑盒子,我在计算机上看到的行为可能与其他人在计算机上看到的行为不同.考虑到这个免责声明,我为两个版本的代码获得的汇编代码是(执行调用的方式略有不同):
call IsEverythingOk
test eax,eax
je AfterIfBody
Run Code Online (Sandbox Code Playgroud)
因此,JIT将优化额外不必要的IL.实际上,在我最初的实验中,该方法IsEverythingOk返回true并且JIT能够完全优化分支.当我切换到在方法中返回一个字段时,JIT将内联调用并直接访问该字段.
底线:你应该期望JIT至少优化瞬态局部变量之类的简单事物,即使代码产生了一些似乎不必要的额外IL.
| 归档时间: |
|
| 查看次数: |
168 次 |
| 最近记录: |