AS3 Math Optimization – int is the new floor()
October 22nd, 2008
UPDATE: The benchmarks on this thread were taken in the Flash 9 Debug player (which includes some crazy bloating) - I've posted an updated set of tests here using the Flash 10 Release player, which should give you a better picture of real-world savings for the majority of web users.
In case you missed my earlier post, I've had a raging Flash-on for optimization lately, and today I'm jumping into the Math class. But first! A little warmup with operators.
I've often heard that addition is fastest, followed by subtraction and multiplication, with division being the slowest but I'd never seen any proof so I threw together my own test:

Way to go subtraction, almost 12% faster than addition! Ok, on to the good stuff. From here on down I'm running 1,000,000 iterations per test, the same test code I used previously, and compiling each test individually about five times (or until I'm satisfied with an average time).
Alright - the Math class. First and foremost this class holds some handy constants so my human meat-brain doesn't have to. The downside is that the AVM doesn't play well with static properties of other classes so there's a pretty significant slowdown. Instead, just retrieve the constant from Math once and store it in a locally scoped variable.

While a lot of the Math methods are invaluable (Math.atan2 == ♥), there are also a few that aren't as complex and slow your swf down unnecessarily. A big one that's easy to work around is the pow method – unless you're doing some heavy lifting with it, you'll see a good boost by keying out your formula by hand:


Or you can replace costly comparison calls with a little logic:



Going a step further, you can take advantage of int casting to shear off any significant digits to the right of the decimal.

By substituting int as a super fast round-down, it's an easy jump to true rounding:

UPDATE: A lot of other people have posted that you can recreate Math.ceil() by using int(i)+1, which never rang true to me – it only works on non-integers. I finally came around to a fix using modulus:
(i % 1) ? int(i) + 1 : i;
I don't have a fancy graph for this one but I benched it around 75% faster than Math.ceil.
My last trick is a monstrous, ugly, hack that I'm hiding over on the code page, it's an approximation for computing sine (which means you can also use it for co-sine by adding π/2 radians). Interestingly, this method of calculating the sine of an angle is actually less efficient and less accurate than the built in method, but the lag from calling the static method pushes Math.sin over the top.

Next: I'm hoping to give arrays a little loving in the not too distant future...if I ever get some free time that is. In the meantime – steer clear of unshift!
Further reading:
Joa Ebert on optimization
Speed tests over on OS Flash
Bitwise gems at Polygonal

January 22nd, 2009 at 5:00 pm
Have you compared these numbers on release and debug players? Any diff for Flash 9 vs Flash 10?
January 22nd, 2009 at 5:19 pm
[...] you’re into Flash coding, you should also read Rob Sampson’s post on AS3 Math Optimization – int is the new floor(). Rob’s been doing ActionScript a lot longer than I have, and I love the historical [...]
January 22nd, 2009 at 6:27 pm
Good catch Ben! I saw this post a couple days ago and I haven’t double checked this stuff yet.
When I posted this, I was using the CS3 IDE (with the debug flag disabled) – so I’m not actually positive if these were running under the debug version of FP9 or the standalone release build – If I ever have free time again I’ll run these in both the release and debug versions of the player and update my graphs.
That said, I would expect the results to be (more or less) the same on all the static calls to Math (except possibly the fastsine approximation) and maybe some upsets in the operator test at the beginning.
December 10th, 2009 at 2:55 pm
int( 0.5 + someNum ) is not actually rounding, it’s doing a Math.ceil.
If someNum is 0 – you get 1.
Even if you use 0.4999, if someNum is 0.0001 your result is 1, not the more accurate 0.
December 10th, 2009 at 3:10 pm
Crap. Nevermind. Actually did some tests and it does work. Weird. Doesn’t seem like it should but it does. Love it!