具有不必要范围的性能

时间:2014-09-29 23:00:27

标签: c# scope readability code-readability

是否会降低性能,或者如果我创建不必要的范围,这是不好的做法? 我的意思是,为了可读性而创建范围:

XmlElement header = list[0] as XmlElement;
if (header == null) throw new Exception("Corrupt header.");

{
    XmlElement subHeader = null; // ...
}

这种方式更易于阅读。有什么理由可以避免这种情况?我刚刚意识到,使相对较长的代码更具可读性是非常好的。特别是因为这不止一次,我必须加载一个主要元素,然后有一些子元素,我可以很容易地在视觉上分开。

专业人士说什么?

1 个答案:

答案 0 :(得分:2)

这不是更具可读性。您的示例代码显示了这一点。

在我看来,这两组代码之间的区别令人困惑:

XmlElement header = list[0] as XmlElement;
if (header == null)
{
    XmlElement subHeader = null; // ...
}


XmlElement header = list[0] as XmlElement;
if (header == null) throw new Exception("Corrupt header.");
{
    XmlElement subHeader = null; // ...
}

此外,如果您的代码相对较长且#34;那么它应该分解为单独的方法,而不是按范围块分组。

现在,就性能而言。这是一个简单的例子:

var text = "Hello";
Console.WriteLine(text);

这变成了这个IL:

IL_0001:  ldstr       "Hello"
IL_0006:  stloc.0     // text
IL_0007:  ldloc.0     // text
IL_0008:  call        System.Console.WriteLine

如果我写这样的代码:

var text = "Hello";
{
    Console.WriteLine(text);
}

IL成为:

IL_0001:  ldstr       "Hello"
IL_0006:  stloc.0     // text
IL_0007:  nop         
IL_0008:  ldloc.0     // text
IL_0009:  call        System.Console.WriteLine
IL_000E:  nop      

请注意nop操作。

对于每个范围块,我在IL中获得一对新的nop操作。但这只发生在调试模式下。在发布模式下,nop操作将被删除。

为了在调试模式下测试性能差异,我写了这段代码:

var sw = Stopwatch.StartNew();
var x = 0L;
for (var y = 0; y < 1000000000L; y++)
{
    {
        x += y;
    }
}
sw.Stop();
Console.WriteLine(x);
Console.WriteLine(sw.ElapsedMilliseconds);

使用额外的范围,它在约3,550毫秒内持续运行。没有额外的范围大约是3,500毫秒。因此性能差异约为1.5%。这只是在调试模式下!

但是考虑到我的操作x += y是如此微不足道,并且性能下降如此微不足道,你可能只是忽略了普通代码中的性能差异。显然,在发布模式代码中完全忽略它。