哪个更快 - 使用块或 Try/Catch/Finally

发布于 2024-09-17 12:42:43 字数 1538 浏览 9 评论 0原文

后续问题

这是这个的 我坚持使用 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 结构是否会比时钟周期更快。

This is a followup question to this

Should I stick with the Try/Catch/Finally construct, or go with the Using construct?

Sample Code for 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

I know what the code would need to be for the Using construct. I just want to know if using the Using construct would be faster comparing clock cycles.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

动听の歌 2024-09-24 12:42:43

不会有性能差异。 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# 中的 try/finally 我们得到:

.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

There won't be a performance difference. using is expanded by the compiler to a try/finally block.

You will see that the following two methods compile to identical 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();
    }
}

The IL generated in the first case is:

.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

In the second case with a try/finally in C# we get:

.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
不再让梦枯萎 2024-09-24 12:42:43

using 编译为 try/catch/finally。我真的看不出有任何语义或性能差异,只要您在手动 try/catch 的情况下正确处置对象即可。

无论如何,请使用 using,因为它会自动为您进行清理(实际上在 finally 子句中)。即使存在性能差异,也可能很小,因此您有更好的地方可以优化。

using compiles into try/catch/finally. I really can't see there being any semantical or performance difference, as long as you properly dispose your object in the case of a manual try/catch.

In any case, go with using, seeing as it does cleanups automagically (actually in the finally clause) for you. Even if there is a performance difference, it is likely so minimal that you have better places to optimize.

醉殇 2024-09-24 12:42:43

我必须相信,相对于您在这些构造中运行的代码,使用与 try/catch 相比不会对性能产生任何差异。

I have to believe that using versus try/catch is not going to make any difference performance wise relative to the code you are running inside those constructs.

囍笑 2024-09-24 12:42:43

Try/Catch/Finally 更快。

1) 6.638 秒:使用标签
2) 6.265 秒:try/catch/finally

我运行了大约十几次。 Try/Catch/Finally 总是名列前茅。

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");

Try/Catch/Finally is faster.

1) 6.638 sec : using tag
2) 6.265 sec : try/catch/finally

I ran this about a dozen times. Try/Catch/Finally always came out on top.

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");
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文