What will be empty to catch and throw a block?

I know the next block is catch and throw

superfluous, I am curious how much damage it can do?

Can the compiler optimize it in release mode? Or will it catch this exception anyway and reverse engineer it? If this is the latter case, what performance penalty will it result in?

try
{
  //...
}
catch {
  throw;
}

      

+1


source to share


1 answer


Optimization

The compiler will not optimize this, even in a Release build.

Accept the following test application:

public class Program {
    public static void Main(string[] args) {
        try {
            CallsThrow();
        }
        catch(Exception ex) {
            Console.WriteLine("Main() caught exception: " + ex.Message);
        }
        Console.Read();
    }

    private static void CallsThrow() {
        try {
            Throw();
        }
        catch {
            throw;
        }
    }

    private static void Throw() {
        throw new Exception("Here my exception.");
    }
}

      

Using ILSpy , we can view the output binary at the IL level . We can see that try

/ catch

in CallsThrow

still exists in our binary Release:

.method private hidebysig static 
    void CallsThrow () cil managed 
{
    // Method begins at RVA 0x2094
    // Code size 11 (0xb)
    .maxstack 1

    .try
    {
        IL_0000: call void JunkCSharpConsole.Program::Throw()
        IL_0005: leave.s IL_000a
    } // end .try
    catch [mscorlib]System.Object
    {
        IL_0007: pop
        IL_0008: rethrow
    } // end handler

    IL_000a: ret
} // end of method Program::CallsThrow

      




Benchmark

Code:

public class Program
{
    public static void Main(string[] args) {
        const int N = 100000000;
#if DEBUG
        const string mode = "Debug";
#else
        const string mode = "Release";
#endif

        Console.WriteLine("Testing {0} iterations in {1} mode:", N, mode);

        // Attempt to JIT / cache
        CallsThrowWithTryCatch(false);
        CallsThrowWithoutTryCatch(false);

        // Test with try/catch+throw
        var s1 = Stopwatch.StartNew();
        for (int i = 0; i < N; i++ )
            CallsThrowWithTryCatch(false);
        s1.Stop();
        Console.WriteLine("  With try/catch: {0} ms", s1.ElapsedMilliseconds);

        // Test without try/catch+throw
        var s2 = Stopwatch.StartNew();
        for (int i = 0; i < N; i++)
            CallsThrowWithoutTryCatch(false);
        s2.Stop();
        Console.WriteLine("  Without try/catch: {0} ms", s2.ElapsedMilliseconds);

        var pct = (s1.ElapsedMilliseconds - s2.ElapsedMilliseconds) / (double)s1.ElapsedMilliseconds * 100.0;
        Console.WriteLine("No try/catch faster by {0:.02}%", pct);

        // Just show that it works
        try {
            CallsThrowWithTryCatch(true);
        }
        catch (Exception ex) {
            Console.WriteLine("Main() caught exception: " + ex.Message);
        }

        // Wait to exit
        Console.WriteLine("Press ENTER to exit.");
        Console.Read();
    }

    private static void CallsThrowWithTryCatch(bool doThrow) {
        try {
            Throw(doThrow);
        }
        catch {
            throw;
        }
    }

    private static void CallsThrowWithoutTryCatch(bool doThrow) {
        Throw(doThrow);
    }

    private static void Throw(bool doThrow) {
        if (doThrow)
            throw new Exception("Here my exception.");
    }
}

      

Results:

Testing 100000000 iterations in Debug mode:
  With try/catch: 1492 ms
  Without try/catch: 1474 ms
No try/catch faster by 1.22%
Main() caught exception: Here my exception.
Press ENTER to exit.

Testing 100000000 iterations in Release mode:
  With try/catch: 598 ms
  Without try/catch: 458 ms
No try/catch faster by 23.42%
Main() caught exception: Here my exception.
Press ENTER to exit.

      

We can see that yes, there is a performance penalty associated with even an empty try

/ catch

. In Debug builds this is not that important, but the Release build showed a significant 23.42% improvement by removing try

/ catch

.

+5


source







All Articles