conditionally compile "Try" section of exception handling

  • Thread starter Thread starter Chirag
  • Start date Start date
C

Chirag

I will soon be working on a embedded device using .NET Compact
Framework where performance is a major issues. Therefore, I would like
the ability to disable exceptions at compile time. I use the below
approach to conditionally compile the "Throw" part of the exception
handling. Is there any elegent (clutter free) way to compile out the
"Try...Catch" portion. This is a concern because I believe the "Try"
statement takes a performance hit by copying the exception handler on
to the stack before actually trying the code. Any ideas?


using System.Diagnostic;
class AClass
{
[Conditional("DEBUG")]
public void DoSomeTest(object objToBeTested)
{
if(skyIsBlue & objToBeTested != null)
throw new UserException();
}

void MyMethod()
{
// only called in debug mode, same as an #if DEBUG
//#endif pair
DoSomeText();
}
}
 
Chirag said:
"Try...Catch" portion. This is a concern because I believe the "Try"
statement takes a performance hit by copying the exception handler on
to the stack before actually trying the code. Any ideas?

These are not C++ exceptions. You cannot get rid of exception support by
not using them. Exceptions are build into the runtime, so you get them
for 'free'. Also, the framework library uses exceptions extensively, so
regardless of whether you decide to use them or not, you will always use
the framework library and hence you will always get exception support.
(For example, WinForms puts a try block around a window's windows
procedure.)

I would be interested to see if you have any performance figures between
code with and code without exceptions. However, I doubt if there will be
any difference.

Richard
 
Chirag said:
I will soon be working on a embedded device using .NET Compact
Framework where performance is a major issues. Therefore, I would like
the ability to disable exceptions at compile time.

Have you actually measured the performance to check that they're
relevant? Surely if you've reached a situation where you'd normally
want to throw an exception, you still need to abort in a pretty hard
manner.

Even on the Compact Framework, exceptions are relatively cheap unless
you're throwing loads and loads of them. Have you measured how many
your app typically throws per second, and how many the device can throw
per second?
 
Not an expert but my understanding of the "exceptions are (relatively)
costly *when raised*" message is that it shouldn't be part of the normal
control flow. I.e. an application shouldn't blindy open a file from a list,
catch the exception raised if the file doesn't exist and continue. It should
use the appropriate method to check first for file existance.

Try perhaps to measure first. It shouldn't be a problem when properly
used...

As a side note, depending on what you are doing you could also use
Debug.Assert (if you want really to test in debug mode that something is
always true) and use exceptions to trap what could happen in release mode...
 
There is a small performance hit (very small) when using a try-catch or
try-finally construct, but unless you are sitting in a tight loop executing
try-catch/finally you will never notice a difference, and the perf "noise"
added is so slight that it gets swamped by all the other performance hits
you take by other code. This overhead is also likely to decrease in future
versions of the runtime. Also, AFAIK the try statement does not copy the
exception handler to the stack. Instead, I believe that the compiler builds
tables of all the try-catch/try-finally blocks and when an exception occurs
the runtime calculates which handler to call based on the code offsets in
these tables.

Bear in mind that the perf hit I am referring to is the the perf cost of
simply writing a try-catch clause, not the runtime cost of throwing an
exception. The runtime cost is significantly higher, but again, as Jon
points out, you are not likely to ever notice it unless, as I said, you are
sitting in a tight loop throwing exceptions on every iteration...so don't do
that (unless you need to). Typically when an exception occurs the code is in
an error-handling path, and the cost of the exception gets included in the
cost of all the other error handling code.

There are strategies you can employ to minimize the number of unwarranted
exceptions the code generates, such as TrySomething (which does not throw
but returns a flag) rather then DoSomething (which throws when an error
occurs).

Also, the construct you show does absolutely nothing to disable exceptions.
As Richard pointed out, exceptions are used extensively by the runtime (and
other libraries) so you cannot disable them just by not throwing your own.
 
Back
Top