For those who don't know, there is a standard C header called setjmp.h that defines two methods: longjmp() and setjmp(). The longjmp works just like a goto statement in C in that, when executed, the program jumps to another pre-defined point in the code, defined by a setjmp. However, where goto is limited to the current, local scope, longjmp can span outside of the current scope and across functions.
If goto is considered harmful, then longjmp() should definitely be considered dangerous. As in, thermo-freakin-nuclear bomb dangerous. Fortunately, its complexity and frequency of use seem to be on par with that of a nuke, and most C developers have not brought it in their everyday. Most. And then there are the folks like Giovanni Verza's predecessor, who left behind functions like this.
/* this subroutine is called thousands of times.
use longjmp instead of loops to increase speed.
Daren 12/03/05 */
void
calculate(struct salesinfo*sales){
jmp_buf buffer;
int i=setjmp(buffer);
if (!(i<sales->count))
RETURN_NOTHING;
addvaluetosubtotal(sales->values[i]);
if (i<sales->count){
longjmp(buffer,i+1);
}
}
Now, while I can maybe see a case for the occasional use of goto to get out of a loop and skip a lot of code in a hurry, I'd readily avise against its use in everyday programming because of the headaches it can cause. But longjmp? I think I'll be avoiding it like the plague. C'mon people,seriously, C is a low level language. If you want to call logic in another function why not, oh I don't know, just CALL THE BLASTED FUNCTION?
Taking the Longjmp Challenge
After reading through the code, I got to wondering, could this performance hack actually...work? For you, dear reader, I have assembled two (semi-)scientific tests to help find the answer.
Links below to source and binaries for the curious and pedantic alike:
Test 1 - Use Longjmp
Test 2 - No Longjmp (Only Loops)
On the Bowytz Megaframe (a.k.a. my home PC running Vista), I created two versions - one where only longjmp functions are used for looping and the other where only loops are used for...er...looping and ran each using Dev-C++ with nothing special added out of the box. Each program did the same thing - sum the values of 15,000 integers, stored in an array, 5,000 times.
The result? When I ran the longjmp version, it took about 4 seconds to finish the summations, but when I ran the looping version, results were near instantaneous.
Sure, 4 seconds isn't exactly a glacial age, but let's assume that a larger array is being processed by the "calculate" function several thousand times a day in a bogged-down Production environment during peak business hours...those 4 seconds over thousands of exeutions add up mighty quick. Since performance boosts are often sprinkled in code as liberally as cheese on pizza, call me crazy, but I have a feeling that Giovanni will be busy making some performance enhancements himself.