Adobe, MAKE SOME NOISE

Benchmarking

{AS3 speed testing, performance}
Here is the code I use to generate my speed benchmarks.

mark I   &bull   mark II

Fast Rounding

{optimized, Math.round(), int}
Using an int-cast instead Math.floor or Math.ceil is an old AS3 trick, but it just occurred to me that you can mod that idea for rounding. In a benchmark this comes out about 15% faster than Math.round().

  1. function round(n:Number):int{
  2. return int(n + .5);
  3. }

Suicidal EventHandler

{self removing, automatic}
I learned this from an old friend and colleague; tuck this little gem into an event handler function and it removes the listener automatically. I use it all the time for anonymous functions (or when I'm too lazy to type out an explicit removeEventListener).

  1. function onSomeEvent(e:Event):void{
  2. e.target.removeEventListener(e.type, arguments.callee);
  3. // ...
  4. }

Array Shifting

{Array, push, pop, shift, unshift}
Some quick code to step through arrays. These work something like tank treads - where the last object in an array is wrapped around and becomes the first. The first line sends the beginner of the array to the back of the line, the second does the opposite and lets the last element cut to the beginning.

Not too tricky but I can never remember which way popping and shifting and pushing go.

  1. // last element becomes [0]
  2. array.unshift(array.pop());
  3.  
  4. // [0] becomes last element
  5. array.push(array.shift());

Fast sine approximation

{sine, cosine, approximation}
For some reason I've been calling Math.sin() and Math.cos() a lot lately. It turns out that since these are static calls, they get slowed down somewhere in the JIT compiler. A quick search led me to a cool fix over in the haXe community, so I hijacked their method and optimized it for AS3.

  1. const PI:Number = Math.PI;
  2. const TWO_PI:Number = PI + PI;
  3. const NEG_PI:Number = -PI;
  4. const QUARTER_PI:Number = 4/PI;
  5. const HALF_PI:Number = PI * .5;
  6. const SIN_ADJUST:Number = .225;
  7.  
  8. function fastsine(theta:Number):Number{
  9. var abstheta:Number, abssin:Number, sin:Number, ret:Number;
  10. if(theta < NEG_PI) theta += TWO_PI else if(theta > PI) theta -= TWO_PI;
  11. (theta < 0) ? abstheta = -theta : abstheta = theta;
  12. sin = (theta - theta * abstheta / PI) * QUARTER_PI;
  13. (sin < 0) ? abssin = -sin : abssin = sin;
  14. ret = (sin + SIN_ADJUST * (sin * abssin - sin));
  15. return ret;
  16. }

So it's not the prettiest code ever, but it gets the job done faster than Math.sin and it's precise to roughly ±.001. To calculate co-sine, use fastSine(angle + HALF_PI);.

Radian / Degree Conversion

{Polar, cartesian, radians, degrees}
I end up using this so often, I thought I'd post it instead of re-typing it for every project.

  1. function radiansToDegrees(r:Number):Number{
  2. return(r * (180 / Math.PI));
  3. }
  4.  
  5. function degreesToRadians(d:Number):Number{
  6. return(d * (Math.PI / 180));
  7. }

Leave a Reply