Try as I might, I just couldn’t find any articles about AS3’s finally keyword. Sure I found Adobe’s documentation, but it seems no one is commenting any further about finally. So today I’ll tackle the performance of what seems to be a straightforward keyword. Could it possibly cause a slowdown? Read on to find out!

As a refresher, the finally keyword is used to hold code that should execute whether or not an exception in a try block is caught by any of the catch blocks. Basically, you can replace this:

try
{
    throw "err";
}
catch (str:String)
{
    doStuff();
    throw "another";
}
doStuff();

With this code that uses finally to eliminate the duplicated doStuff code:

try
{
    throw "err";
}
catch (str:String)
{
    throw "another";
}
finally
{
    doStuff();
}

So what if you simply added an empty finally block? Would that cause any slowdown? It has no code at all so it shouldn’t, but strange things sometimes happen with Flash’s compiler, JIT, and VM, so let’s put it to the test to see if everything checks out:

package
{
	import flash.utils.getTimer;
	import flash.display.Sprite;
	import flash.display.StageAlign;
	import flash.display.StageScaleMode;
	import flash.text.TextField;
	import flash.text.TextFieldAutoSize;
 
	public class FinallyKeyword extends Sprite
	{
		private var __logger:TextField = new TextField();
		private function row(...cols): void
		{
			__logger.appendText(cols.join(",")+"\n");
		}
 
		public function FinallyKeyword()
		{
			stage.align = StageAlign.TOP_LEFT;
			stage.scaleMode = StageScaleMode.NO_SCALE;
 
			__logger.autoSize = TextFieldAutoSize.LEFT;
			addChild(__logger);
 
			init();
		}
 
		private function init(): void
		{
			var beforeTime:int;
			var afterTime:int;
			var REPS:int = 1000000;
			var i:int;
 
			row("Test", "Time");
 
			beforeTime = getTimer();
			for (i = 0; i < REPS; ++i)
			{
				testFinally();
			}
			afterTime = getTimer();
			row("finally", (afterTime-beforeTime));
 
			beforeTime = getTimer();
			for (i = 0; i < REPS; ++i)
			{
				testNoFinally();
			}
			afterTime = getTimer();
			row("no finally", (afterTime-beforeTime));
		}
 
		private function testFinally(): void
		{
			try
			{
				try
				{
					throw "err";
				}
				catch (str:String)
				{
					throw "err2";
				}
				finally
				{
 
				}
			}
			catch (str2:String)
			{
			}
			finally
			{
			}
		}
 
		private function testNoFinally(): void
		{
			try
			{
				try
				{
					throw "err";
				}
				catch (str:String)
				{
					throw "err2";
				}
			}
			catch (str2:String)
			{
			}
		}
	}
}

I ran this test app in the following environment:

  • Flex SDK (MXMLC) 4.6.0.23201, compiling in release mode (no debugging or verbose stack traces)
  • Release version of Flash Player 11.4.402.265
  • 2.3 Ghz Intel Core i7
  • Mac OS X 10.8.2

And here are the results I got:

Test Time
finally 1445
no finally 1156

Finally Keyword Performance Graph

What!? We simply added a finally block with no code in it and managed to slow down the test by 25%! So while finally can (arguably) help clean up the style of your code, it certainly comes with a hefty overhead. Use it only outside of performance critical code. Then again, you really shouldn’t be using try/catch for performance critical code if you can help it.

Spot a bug? Have a suggestion? Post a comment!