代码之家  ›  专栏  ›  技术社区  ›  crackedcornjimmy

哪个更快-一个using块或try/catch/finally

  •  6
  • crackedcornjimmy  · 技术社区  · 16 年前

    这是一个后续问题 this

    我应该坚持使用try/catch/finally构造,还是使用using构造?

    Try/Catch/Finally的示例代码:

    Dim oRequest As WebRequest
    Dim oResponse As HttpWebResponse = Nothing
    Dim dataStream As Stream = Nothing
    Dim reader As StreamReader = Nothing
    Dim responseFromServer As String
    
    Try
            sNewCustomerURL = NewCustomerQueryStringPrepare()
    
        'make the call to the webservice to add a new customer
        oRequest = WebRequest.Create(sNewCustomerURL)
    
        oRequest = CType(oRequesC, HttpWebRequest)
        oRequest.Method = "GET"
        oResponse = CType(oRequest.GetResponse(), HttpWebResponse)
    
        dataStream = oResponse.GetResponseStream()
        reader = New StreamReader(dataStream)
        responseFromServer = reader.ReadToEnd()
    
            Dim xml As New XmlDocument()
        xml.LoadXml(responseFromServer)
        Dim node As XmlNodeList = xml.GetElementsByTagName("SUCCESS")
        Dim value = CBool(node(0).InnerText)
    
        'do stuff               
    
    
    Catch ex As Exception
    
           'process exception
    
    Finally
    
        'do cleanup
        oRequest = Nothing
        If Not oResponse Is Nothing Then
            oResponse.Close()
        End If
        oResponse = Nothing
        If Not reader Is Nothing Then
            reader.Close()
        End If
        reader = Nothing
        If Not dataStream Is Nothing Then
            dataStream.Flush()
            dataStream.Close()
        End If
        dataStream = Nothing
    End Try
    

    我知道使用构造需要什么代码。我只想知道使用using结构是否比时钟周期更快。

    4 回复  |  直到 14 年前
        1
  •  9
  •   Dirk Vollmar    16 年前

    不会有性能差异。 using 由编译器扩展为try/finally块。

    您将看到以下两个方法编译为相同的IL。

    void SampleWithUsing()
    {
        using (MemoryStream s = new MemoryStream())
        {
            s.WriteByte(1);
        }
    }
    
    void SampleWithTryFinally()
    {
        MemoryStream s = new MemoryStream();
        try
        {
            s.WriteByte(1);
        }
        finally
        {
            if (s != null) s.Dispose();
        }
    }
    

    第一种情况下生成的IL是:

    .method private hidebysig instance void  SampleWithUsing() cil managed
    {
      // Code size       26 (0x1a)
      .maxstack  2
      .locals init ([0] class [mscorlib]System.IO.MemoryStream s)
      IL_0000:  newobj     instance void [mscorlib]System.IO.MemoryStream::.ctor()
      IL_0005:  stloc.0
      .try
      {
        IL_0006:  ldloc.0
        IL_0007:  ldc.i4.1
        IL_0008:  callvirt   instance void [mscorlib]System.IO.Stream::WriteByte(uint8)
        IL_000d:  leave.s    IL_0019
      }  // end .try
      finally
      {
        IL_000f:  ldloc.0
        IL_0010:  brfalse.s  IL_0018
        IL_0012:  ldloc.0
        IL_0013:  callvirt   instance void [mscorlib]System.IDisposable::Dispose()
        IL_0018:  endfinally
      }  // end handler
      IL_0019:  ret
    } // end of method Program::SampleWithUsing
    

    在第二种情况下,在C中尝试/最终,我们得到:

    .method private hidebysig instance void  SampleWithTryFinally() cil managed
    {
      // Code size       26 (0x1a)
      .maxstack  2
      .locals init ([0] class [mscorlib]System.IO.MemoryStream s)
      IL_0000:  newobj     instance void [mscorlib]System.IO.MemoryStream::.ctor()
      IL_0005:  stloc.0
      .try
      {
        IL_0006:  ldloc.0
        IL_0007:  ldc.i4.1
        IL_0008:  callvirt   instance void [mscorlib]System.IO.Stream::WriteByte(uint8)
        IL_000d:  leave.s    IL_0019
      }  // end .try
      finally
      {
        IL_000f:  ldloc.0
        IL_0010:  brfalse.s  IL_0018
        IL_0012:  ldloc.0
        IL_0013:  callvirt   instance void [mscorlib]System.IO.Stream::Dispose()
        IL_0018:  endfinally
      }  // end handler
      IL_0019:  ret
    } // end of method Program::SampleWithTryFinally
    
        2
  •  2
  •   user438034    14 年前

    using 编译成 try / catch / finally . 我真的看不出有任何语义或性能上的区别,只要你在手册的情况下正确地处理你的对象。 尝试 / 抓住 .

    不管怎样,继续 使用 ,就像它自动清理一样(实际上在 最后 条款)。即使存在性能差异,它也可能非常小,以至于您有更好的地方进行优化。

        3
  •  0
  •   E.J. Brennan    16 年前

    我必须相信,相对于您在这些构造中运行的代码,使用和Try/Catch不会对性能产生任何影响。

        4
  •  0
  •   tidwall    16 年前

    Try/Catch/Finally更快。

    1)6.638秒:使用标签
    2)6.265秒:尝试/捕获/最终

    我跑了十几次。尝试/抓住/最后总是出类拔萃。

    DateTime start = DateTime.Now;
    for (int i = 0; i < 50000000; i++)
    {
        using (MemoryStream s = new MemoryStream())
        {
            s.WriteByte(1);
        }
    }
    Console.WriteLine(DateTime.Now.Subtract(start) + " seconds");
    start = DateTime.Now;
    for (int i = 0; i < 50000000; i++)
    {
        MemoryStream s = null;
        try
        {
            s = new MemoryStream();
            s.WriteByte(1);
        }
        catch { }
        finally
        {
            if (s != null) s.Dispose();
        }
    }
    Console.WriteLine(DateTime.Now.Subtract(start) + " seconds");