Wednesday, June 18, 2008

Zero-cost exception?

Like any code monkey that have been around for a while, I have assembled from my various experiences (BeOS, QNX, Symbian, Win32 ...) a particular coding style and set of paradigms/concepts I like to use for my own projects. When I start on a new platform, I usually have to adapt my style to what is available and/or most commonly used on the platform, and this is usually a good exercise that goes hand-in-hand with learning a new environment. Since I have picked-up the usage of exception for error handling from my mobile development days at Nokia, this is one of the first thing I have been looking at when starting with Objective-C. Now, I'm not going, in this blog, to join the on-going debate raging in the software community about the pros&cons of using exceptions vs. returning error codes, however I should state that I do prefers to use exceptions as they allow for a more elegant and clean (meaning readable) code (IMHO).

After finding a couple of references (can't find the link now) to the fact that Objective-C's exception handling is not as efficient as C++ (meaning not zero-cost), I decided that I should try to check that out. For that purpose I wrote a simple (and naive) test program which measure the elapsed time for a loop calling a function containing either a try/catch block or a old fashion if statement. Here is the function been called repeatedly:
void loop(Foo* aFoo)
{
static int i=0;
#ifdef _EXCEPTION
@try {
[aFoo doSomeL:i++];
} @catch(NSException* lException) {
printf("An exception was thrown!\n");
} @finally {
}
#else
if([aFoo doSome:i++] == NO)
printf("An error occured!\n");
#endif
}
The Foo object here used is of no real importance. In both path the message been sent will compare the value passed as argument and will return an error or throw an exception when an hard-coded value is reached within the loop. Since my immediate concern was the cost of try/catch block, I had set the hard-coded value to be higher than the loop range so that even if the test was been performed at each loop, it will not trigger an error or exception.

I was rather disappointed when I ran the program with if statement then with the try/catch block and noted than the later was 8.2 times slower (without any exception been throw). Since my understanding was that Objective-C's exception handling on 64-bit had been improved compared to 32-bit with 10.5 (see bottom of release notes), I'm definitely surprised considering that I was testing this on an iMac (Intel Core Duo 2, gcc 4.0). Now, it is possible that I'm doing something wrong ... I'll have to double check that I was indeed compiling for 64-bit, which I assumed was the case since I believe that gcc will use this mode per default on a 64-bit machine (at least that's the way it work on Linux).

Since I have easy access to a x64 Linux box (gcc 4.1 with Objective-C support), I quickly adapted my test to the absence of Cocoa and noted with than the cost of the try/catch block was only 1.03 times higher than an if statement ... evidently zero-cost as advertised. So what it's going on with OS-X?

No comments: