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.
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
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.
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.
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");
精彩评论