Что быстрее - Использование блока или Try / Catch / Наконец - PullRequest
6 голосов
/ 03 сентября 2010

Это дополнительный вопрос к this

Должен ли я придерживаться конструкции Try / Catch / finally или перейти к конструкции Using?

Пример кода дляПопробуйте / Catch / Наконец:

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.Я просто хочу знать, будет ли использование конструкции Using быстрее сравнивать тактовые циклы.

Ответы [ 4 ]

9 голосов
/ 03 сентября 2010

Не будет разницы в производительности.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 голосов
/ 03 сентября 2010

using компилируется в try / catch / finally. Я действительно не вижу никакой разницы в семантике или производительности, если вы правильно распоряжаетесь своим объектом в случае руководства try / catch.

В любом случае, используйте using, так как он выполняет очистку автоматически (на самом деле в предложении finally) для вас. Даже если есть разница в производительности, она, вероятно, настолько минимальна, что у вас есть лучшие места для оптимизации.

0 голосов
/ 03 сентября 2010

Try / Catch / Наконец быстрее.

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");
0 голосов
/ 03 сентября 2010

Я должен верить, что использование vs. try / catch не повлияет на производительность по сравнению с кодом, который вы запускаете внутри этих конструкций.

...