Prova ad aumentare il mio codice?

Ho scritto un codice per testare l’impatto del try-catch, ma ho visto alcuni risultati sorprendenti.

static void Main(string[] args) { Thread.CurrentThread.Priority = ThreadPriority.Highest; Process.GetCurrentProcess().PriorityClass = ProcessPriorityClass.RealTime; long start = 0, stop = 0, elapsed = 0; double avg = 0.0; long temp = Fibo(1); for (int i = 1; i < 100000000; i++) { start = Stopwatch.GetTimestamp(); temp = Fibo(100); stop = Stopwatch.GetTimestamp(); elapsed = stop - start; avg = avg + ((double)elapsed - avg) / i; } Console.WriteLine("Elapsed: " + avg); Console.ReadKey(); } static long Fibo(int n) { long n1 = 0, n2 = 1, fibo = 0; n++; for (int i = 1; i < n; i++) { n1 = n2; n2 = fibo; fibo = n1 + n2; } return fibo; } 

Sul mio computer, questo costantemente stampa un valore intorno a 0,96 ..

Quando avvolgo il ciclo for all’interno di Fibo () con un blocco try-catch come questo:

 static long Fibo(int n) { long n1 = 0, n2 = 1, fibo = 0; n++; try { for (int i = 1; i < n; i++) { n1 = n2; n2 = fibo; fibo = n1 + n2; } } catch {} return fibo; } 

Ora stampa costantemente 0,69 … – in realtà corre più veloce! Ma perché?

Nota: l’ho compilato utilizzando la configurazione Release e ho eseguito direttamente il file EXE (all’esterno di Visual Studio).

EDIT: l’ eccellente analisi di Jon Skeet mostra che try-catch sta in qualche modo facendo sì che il CLR x86 usi i registri della CPU in un modo più favorevole in questo caso specifico (e penso che dobbiamo ancora capire perché). Ho confermato che Jon ha scoperto che il CLR x64 non ha questa differenza e che era più veloce del CLR x86. Ho anche provato a utilizzare i tipi int all’interno del metodo Fibo invece dei tipi long , quindi il CLR x86 era altrettanto veloce del CLR x64.


AGGIORNAMENTO: Sembra che questo problema sia stato risolto da Roslyn. Stessa macchina, stessa versione CLR – il problema rimane come sopra quando compilato con VS 2013, ma il problema scompare quando compilato con VS 2015.