Make a Little House

RSS

Posts tagged with "flash"

Dec 3

Super simple Metrics in ActionScript 3

Flex Builder’s Flash Builder’s profiler is great for finding bottlenecks in your application. But when optimizating specific methods and calls, you may find the profiler is overkill…and often tedious to get rolling.

I created a simple Metrics class that let’s me output time in milli’s between designated start and end points. Nothing mind-blowingly slick or clever here. Just useful. It even works on recursive calls. I usually override the log method use Flex’s debug targets, but trace is fine.

Here’s how you use it:

var metrics:Metrics = Metrics.getInstance();
var tk:String = metrics.startTimeTrace( "traceExample" );
				
// Put some cool and expensive code here...
				
metrics.endTimeTrace( tk );

And here’s the class:

package bb.util
{

    public class Metrics
    {
        // Set this static variable false in your code when you do not want
        // to output the time tracking information but do not want to remove
        // your start and end calls. Alternatively, replace
        // the trace with a logging system.
        public static var showOutput:Boolean = true;

        private const LEN:Number = 10;
        private const PREFIX:String = "_inst_";
        private var hash:Object;
        private static var _instance:Metrics = null;

        /**
         * Constructor.
         */
        public function Metrics()
        {

        }

        /**
         * Singleton accessor.
         *
         * @return The Singleton instance.
         */
        public static function getInstance():Metrics
        {
            if ( !_instance )
            {
                _instance = new Metrics();
                _instance.hash = {};
            }

            return _instance;
        }

        /**
         * Starts a timer.
         *
         * @param name	The name used to identify a particular trace thread.
         * @returns		A String token used to indentify the thread to track. Pass
         * 				this token back when ending the trace.
         * @see			endTimeTrace
         */
        public function startTimeTrace( name:String ):String
        {
            var startTime:Date;
            var newKey:String;

            do
            {
                newKey = getKey( name );
            } while ( this.hash[ newKey ] );

            startTime = new Date();
            this.hash[ newKey ] = { name: name, startTime: startTime };

            return newKey;
        }

        /**
         * Ends a timer.
         *
         * @param key	The token used to identify a particular trace thread which
         * 				is returned with startTimeTrace.
         * @see			startTimeTrace
         * @throws	An error if a corresponding token is not found
         */
        public function endTimeTrace( token:String ):Number
        {
            var rez:Number;
            var endTime:Date = new Date();
            var vo:Object = this.hash[ token ];

            if ( !vo )
            {
                throw new Error( “Metrics error: unknown token: ” + token );
            }

            rez = endTime.getTime() - vo.startTime.getTime();
            log( “Metrics::” + vo.name + ” -> ” + rez / 1000 + ” seconds.” );
            hash[ token ] = null;
            delete hash[ token ];

            return rez;
        }

        // Generates a psuedo-random token for keying
        private function getKey( seed:String ):String
        {
            var newKey:String;
            newKey = seed + PREFIX + StringUtils.generateRandomString( LEN );
            return newKey;
        }

        // Override or edit this to output data however you like
        protected function log( dataString:String ):void
        {
            if ( showOutput )
            {
                trace( dataString );
            }
        }
    }
}