Try/catch blocks are certainly a nice feature to have. They allow you to catch errors that are beyond your control and handle them in a nice manner. They also allow you to throw your own errors and handle them in the same way. This would all be great if it weren’t for the fact that they are tremendously slow. Read on for some surprising test results.

Here is a very simple test to demonstrate the slowdown:

function init(): void
{
	var beforeTime:int = getTimer();
	var sum:int = 0;
	for (var i:int = 0; i < 100000000; ++i)
	{
		sum += i;
	}
	var afterTime:int = getTimer();
	trace("No try-catch: " + (afterTime-beforeTime));
 
	beforeTime = getTimer();
	try
	{
		sum = 0;
		for (i = 0; i < 100000000; ++i)
		{
			sum += i;
		}
	}
	catch (err:Error)
	{
	}
	afterTime = getTimer();
	trace("Try-catch: " + (afterTime-beforeTime)); 
}

And here are the results I get on a 3.0 Ghz Intel Core 2 Duo with 2GB of RAM running Windows XP when printing it out every frame:

No try-catch: 271
Try-catch: 478
No try-catch: 288
Try-catch: 655
No try-catch: 271
Try-catch: 473
No try-catch: 270
Try-catch: 474
No try-catch: 270
Try-catch: 652
No try-catch: 271
Try-catch: 662
No try-catch: 273
Try-catch: 475
No try-catch: 272
Try-catch: 474
No try-catch: 271
Try-catch: 645
No try-catch: 271
Try-catch: 653
No try-catch: 272
Try-catch: 469
No try-catch: 271
Try-catch: 477
No try-catch: 273
Try-catch: 653
No try-catch: 270
Try-catch: 659
No try-catch: 270
Try-catch: 476
No try-catch: 270
Try-catch: 473
No try-catch: 270
Try-catch: 657
No try-catch: 274
Try-catch: 652
No try-catch: 271
Try-catch: 477
No try-catch: 273
Try-catch: 475
No try-catch: 272
Try-catch: 665

It’s 2-3x slower! Notice that the function that uses a try/catch block does not actually throw an error and that the try/catch block is also not within the loop. This is simply measuring the speed of code executing within a try block. One popular technique is to wrap the main ENTER_FRAME listener for an app that subsequently updates many other areas with a try/catch block. This will result in an overall performance decrease of 2-3x for all AS3 called from within that try/catch block. I therefore strongly recommend not using such a try/catch in released versions of the app. It can still be useful for debugging, but it should be considered bad practice for released versions.

In conclusion, try/catch blocks are a mixed blessing. They can be very handy and result in very clean code, but they are performance killers in AS3. If you are used to C++ and its very fast exception handling, this can be quite a shock. Perhaps the global error handler in Flash Player 10.1 will help us get the best of both worlds.