2010-09-02 7 views
6

Questa è una domanda successore del thische è più veloce - un blocco con o try/catch/finally

Devo rimanere con il try/catch/finally costruire, o andare con il costrutto Utilizzando?

Codice di esempio per 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 

so quello che il codice avrebbe bisogno di essere per la costruzione di utilizzo. Voglio solo sapere se usare il costrutto Using sarebbe più veloce confrontando i cicli di clock.

+11

tag 'using' molto più veloce . Mi ha salvato circa 5 secondi di digitazione. – tidwall

risposta

9

Non ci sarà una differenza di prestazioni. using viene espanso dal compilatore in un blocco try/finally.

Vedrete che i seguenti due metodi compilano per IL identico.

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(); 
    } 
} 

L'IL generato nel primo caso è:

 
.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 

Nel secondo caso con un try/finally in C# si ottiene:

 
.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 
+0

Ti manca la presa lì. – tidwall

+0

@jojaba: Beh, ho deciso di non cogliere l'esempio per semplicità. Se ti aspetti che il corpo dell'istruzione usando per lanciarti possa aggiungere un tentativo/cattura. Ma tieni presente che per un confronto equo dovresti aggiungere la cattura a entrambi i metodi, ad esempio aggiungere un trucco alla versione try/finally * e * aggiungere un blocco try/catch all'interno o all'esterno dell'istruzione using. –

0

Devo credere che l'uso di versus try/catch non farà alcuna differenza in termini di prestazioni rispetto al codice che si sta eseguendo all'interno di questi costrutti.

2

using compila in try/catch/finally. Non riesco davvero a vedere che ci siano differenze semantiche o prestazionali, a condizione di disporre correttamente dell'oggetto nel caso di un manuale try/catch.

In ogni caso, andare con using, visto che pulisce automagicamente (in realtà nella clausola finally) per voi. Anche se c'è una differenza di prestazioni, è probabile che sia così minimo che hai posti migliori da ottimizzare.

0

Try/Catch/Finalmente è più veloce.

1) 6,638 sec: utilizzando tag
2) 6,265 sec: try/catch/finally

mi sono imbattuto questo circa una dozzina di volte. Prova/Catch/Finalmente è sempre uscito in cima.

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

Il benchmark presenta alcuni problemi. I più importanti sono: Usa un 'Cronometro' per misurare e non' DateTime.Now'. 'Cronometro' utilizza un contatore delle prestazioni e ti dà una maggiore precisione. Quindi, esegui il codice senza prima misurare, potrebbe esserci qualche tempo di riscaldamento misurato dal tuo campione. –

+1

In effetti, otterrete il risultato opposto se mettete prima il ciclo try/finally per-loop nel codice e poi misurate il ciclo usando. –

Problemi correlati