Try/Catch Slowdown
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.
#1 by Dan on October 14th, 2009 ·
Very good to know! :D
#2 by Peter on October 14th, 2009 ·
Thanks for sharing.
Typical real world applications will not halt the LLVM for 100000000 iterations; therefore the slowness will negligible. Hopefully 10.1 will address this.
#3 by jackson on October 15th, 2009 ·
And thank you for the comment. I have made it the subject of tomorrow’s article. I’d love to hear your thoughts on it.
#4 by nicothezulu on December 3rd, 2013 ·
Hi there!
First of all, thank you for your blog posts! They are really cool, thanks for them.
Actually i want to get rid of a try catch block to have some speedup, hope u can help.
Scenario is, that i want to get a reference to a non existing element in a 2d array object…
like array[a][b] …. because of the algorythm there is possible i am referencing out of the array, but can’t catch it without a try catch, so i got runtime error 1010: A term is undefined and has no properties if i dont use trycatch.
how can i solve this without that catch? tried already if(box), if(box!=undefined), if(box!==undefined)…..
#5 by jackson on December 3rd, 2013 ·
Hi. I think what you need to do is check if the result of the first index is undefined. For example:
Alternatively, you could use the
in
operator:If performance is really critical here, you might want to run a performance test to see which is faster.
Hope that helps.
#6 by nicothezulu on December 3rd, 2013 ·
Thank you for the quick reply, i will try (and catch :) ) and let u know the results.