We\'ve seen plenty of questions about when and why to use try
/catch
and try
/catch
/finally
. And I know there\
Let's actually put some benchmark numbers to this. What this benchmark shows is that, indeed, the time of having a try/finally is about as small as the overhead of a call to an empty function (probably better put: "a jump to the next instruction" as the IL expert stated it above).
static void RunTryFinallyTest()
{
int cnt = 10000000;
Console.WriteLine(TryFinallyBenchmarker(cnt, false));
Console.WriteLine(TryFinallyBenchmarker(cnt, false));
Console.WriteLine(TryFinallyBenchmarker(cnt, false));
Console.WriteLine(TryFinallyBenchmarker(cnt, false));
Console.WriteLine(TryFinallyBenchmarker(cnt, false));
Console.WriteLine(TryFinallyBenchmarker(cnt, true));
Console.WriteLine(TryFinallyBenchmarker(cnt, true));
Console.WriteLine(TryFinallyBenchmarker(cnt, true));
Console.WriteLine(TryFinallyBenchmarker(cnt, true));
Console.WriteLine(TryFinallyBenchmarker(cnt, true));
Console.ReadKey();
}
static double TryFinallyBenchmarker(int count, bool useTryFinally)
{
int over1 = count + 1;
int over2 = count + 2;
if (!useTryFinally)
{
var sw = Stopwatch.StartNew();
for (int i = 0; i < count; i++)
{
// do something so optimization doesn't ignore whole loop.
if (i == over1) throw new Exception();
if (i == over2) throw new Exception();
}
return sw.Elapsed.TotalMilliseconds;
}
else
{
var sw = Stopwatch.StartNew();
for (int i = 0; i < count; i++)
{
// do same things, just second in the finally, make sure finally is
// actually doing something and not optimized out
try
{
if (i == over1) throw new Exception();
} finally
{
if (i == over2) throw new Exception();
}
}
return sw.Elapsed.TotalMilliseconds;
}
}
Result: 33,33,32,35,32 63,64,69,66,66 (milliseconds, make sure you have code optimization on)
So about 33 milliseconds overhead for the try/finally in 10 million loops.
Per try/finally then, we are talking 0.033/10000000 =
3.3 nanoseconds or 3.3 billionth of a second overhead of a try/finally.