使用多个"using"语句会如何影响性能?

3

我不反对使用 "Using" 语句,但我想知道当我们在一个 "Using" 语句内部使用另一个 "Using" 语句时,它会如何影响性能。

例如:

        using (test1 (type1))
        {
            using (test2(type2))
            {
                using (test2(type3))
                {
                }
            }
        }

这个会被翻译成IL,就像这样:

        try
        {
            try
            {
                try
                {
                }
                finally
                {
                }
            }
            finally
            {
            }
        }
        finally
        { 
        }

这将增加程序集的大小,我相信会影响应用程序的性能,对吗?

我们不应该使用这个吗?

        type1 test1 = new type1;
        type2 test2 = new type2;
        type3 test3 = new type3;

        try
        {

        }
        finally
        {
          test1.Dispose;
          test2.Dispose;
          test3.Dispose;
        }
4个回答

25

不要使用您的第二个形式。如果test1.Dispose()由于某种原因抛出异常,则test2.Dispose()test3.Dispose()将无法被调用。

如果有任何性能差异,那么它将是微不足道的。不要为了微不足道的性能而放弃正确性 :)


谢谢,我没有想到那个 ;)。 - Bruno Costa
今日思考:不要为了微不足道的性能牺牲准确性。 - Gary Willoughby
我完全同意,请参考此文章http://www.codinghorror.com/blog/archives/001218.html以获取另一种“微观优化” - WACM161

6
我认为您正在寻找以下内容:
using (test1(type1))
using (test2(type2))
using (test3(type3))
{
    // Code using test1/test2/test3 goes here.
}

这段代码等同于你问题中的第一个try-finally语句,但显然更易读。不必担心性能,好的设计实践和使用嵌套方法(正如之前的帖子所指出的那样)是强健的,而且多重使用语句使得代码更加易读。


这个程序仍然会扩展到三个try/finally块 - 正如被接受的答案所指出的那样,这是正确的。显而易见的好处是可读性。 - Dan C.
抱歉,你是正确的。它确实会扩展为三个try-finally块。 - Noldorin

5

我认为我们通常不需要为了编写更复杂、难以维护的代码而担心程序集的大小!

你的示例代码恰好说明了我们为什么需要编译器生成它所生成的代码。如果你对 new type2() 的调用失败,那么 test1 上的 Dispose 方法将永远不会被调用,这将导致资源泄漏。


1

除非抛出异常,否则try/catch/finally不会太消耗资源。而且即使抛出异常,一些人(包括Jon Skeet)也曾说过抛出异常并不是那么耗费资源。

话虽如此,显然你不应该将异常用于控制流程。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接