Today’s article is about the basic operators that make up most languages, and in particular AS3. Without them there wouldn’t be much of a language. So it would seem vitally important that we know how they perform relative to each other. Is shifting faster than adding? Adding faster than multiplying? Multiplying faster than dividing? Does the type of the operands matter? Read on for the results in high detail. Update: see my comment below for an important change to the results.

For this test I ripped a list of operators straight from Adobe’s AS3 documentation. I then tested using the int, uint, and Number types, which are the only types that really apply to many of them. Sure Boolean applies in some cases—especially logical operators—but there are so many bitwise and arithmetic operators that just don’t apply. Further, I mixed the types to see how the operators change speed when dealing with operands of two different types. The result is this very long, very repetitive, yet very simple test application:

package
{
    import flash.display.*;
    import flash.events.*;
    import flash.utils.*;
    import flash.text.*;
 
    /**
    *   An app to test operator performance
    *   @author Jackson Dunstan
    */
    public class BitwisePerformance extends Sprite
    {
        public function BitwisePerformance()
        {
            addEventListener(Event.ENTER_FRAME, onEnterFrame);
        }
        public function onEnterFrame(ev:Event): void
        {
            removeEventListener(Event.ENTER_FRAME, onEnterFrame);
 
            var logger:TextField = new TextField();
            function log(msg:*): void { logger.appendText(msg + "\n"); }
            logger.autoSize = TextFieldAutoSize.LEFT;
            addChild(logger);
 
            const REPS:int = 50000000;
            var i:int;
            var beforeTime:int;
            var afterTime:int;
            var val1int:int;
            var val2int:int;
            var val1uint:uint;
            var val2uint:uint;
            var val1number:Number;
            var val2number:Number;
 
            function init(): void
            {
                val1int = 1;
                val2int = 2;
                val1uint = 1;
                val2uint = 2;
                val1number = 1;
                val2number = 2;
            }
 
            log("int");
            init();
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1int & val2int;
            }
            afterTime = getTimer();
            log("\t&: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1int | val2int;
            }
            afterTime = getTimer();
            log("\t|: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1int ^ val2int;
            }
            afterTime = getTimer();
            log("\t^: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                ~val1int;
            }
            afterTime = getTimer();
            log("\t~: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1int >> val2int;
            }
            afterTime = getTimer();
            log("\t>>: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1int >>> val2int;
            }
            afterTime = getTimer();
            log("\t>>>: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1int << val2int;
            }
            afterTime = getTimer();
            log("\t<<: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1int + val2int;
            }
            afterTime = getTimer();
            log("\t+: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1int - val2int;
            }
            afterTime = getTimer();
            log("\t-: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1int * val2int;
            }
            afterTime = getTimer();
            log("\t*: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1int / val2int;
            }
            afterTime = getTimer();
            log("\t/: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1int % val2int;
            }
            afterTime = getTimer();
            log("\t%: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1int++;
            }
            afterTime = getTimer();
            log("\t++: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1int--;
            }
            afterTime = getTimer();
            log("\t--: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1int == val2int;
            }
            afterTime = getTimer();
            log("\t==: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1int === val2int;
            }
            afterTime = getTimer();
            log("\t===: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1int != val2int;
            }
            afterTime = getTimer();
            log("\t!=: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1int !== val2int;
            }
            afterTime = getTimer();
            log("\t!==: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1int > val2int;
            }
            afterTime = getTimer();
            log("\t>: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1int >= val2int;
            }
            afterTime = getTimer();
            log("\t>=: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1int < val2int;
            }
            afterTime = getTimer();
            log("\t<=: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1int && val2int;
            }
            afterTime = getTimer();
            log("\t&&: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1int || val2int;
            }
            afterTime = getTimer();
            log("\t||: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                !val1int;
            }
            afterTime = getTimer();
            log("\t!: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1int = val2int;
            }
            afterTime = getTimer();
            log("\t=: " + (afterTime-beforeTime));
 
            log("uint");
            init();
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1uint & val2uint;
            }
            afterTime = getTimer();
            log("\t&: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1uint | val2uint;
            }
            afterTime = getTimer();
            log("\t|: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1uint ^ val2uint;
            }
            afterTime = getTimer();
            log("\t^: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                ~val1uint;
            }
            afterTime = getTimer();
            log("\t~: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1uint >> val2uint;
            }
            afterTime = getTimer();
            log("\t>>: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1uint >>> val2uint;
            }
            afterTime = getTimer();
            log("\t>>>: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1uint << val2uint;
            }
            afterTime = getTimer();
            log("\t<<: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1uint + val2uint;
            }
            afterTime = getTimer();
            log("\t+: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1uint - val2uint;
            }
            afterTime = getTimer();
            log("\t-: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1uint * val2uint;
            }
            afterTime = getTimer();
            log("\t*: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1uint / val2uint;
            }
            afterTime = getTimer();
            log("\t/: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1uint % val2uint;
            }
            afterTime = getTimer();
            log("\t%: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1uint++;
            }
            afterTime = getTimer();
            log("\t++: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1uint--;
            }
            afterTime = getTimer();
            log("\t--: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1uint == val2uint;
            }
            afterTime = getTimer();
            log("\t==: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1uint === val2uint;
            }
            afterTime = getTimer();
            log("\t===: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1uint != val2uint;
            }
            afterTime = getTimer();
            log("\t!=: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1uint !== val2uint;
            }
            afterTime = getTimer();
            log("\t!==: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1uint > val2uint;
            }
            afterTime = getTimer();
            log("\t>: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1uint >= val2uint;
            }
            afterTime = getTimer();
            log("\t>=: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1uint < val2uint;
            }
            afterTime = getTimer();
            log("\t<=: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1uint && val2uint;
            }
            afterTime = getTimer();
            log("\t&&: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1uint || val2uint;
            }
            afterTime = getTimer();
            log("\t||: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                !val1uint;
            }
            afterTime = getTimer();
            log("\t!: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1uint = val2uint;
            }
            afterTime = getTimer();
            log("\t=: " + (afterTime-beforeTime));
 
            log("int/uint");
            init();
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1int & val2uint;
            }
            afterTime = getTimer();
            log("\t&: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1int | val2uint;
            }
            afterTime = getTimer();
            log("\t|: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1int ^ val2uint;
            }
            afterTime = getTimer();
            log("\t^: " + (afterTime-beforeTime));
 
            log("\t~: n/a");
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1int >> val2uint;
            }
            afterTime = getTimer();
            log("\t>>: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1int >>> val2uint;
            }
            afterTime = getTimer();
            log("\t>>>: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1int << val2uint;
            }
            afterTime = getTimer();
            log("\t<<: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1int + val2uint;
            }
            afterTime = getTimer();
            log("\t+: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1int - val2uint;
            }
            afterTime = getTimer();
            log("\t-: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1int * val2uint;
            }
            afterTime = getTimer();
            log("\t*: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1int / val2uint;
            }
            afterTime = getTimer();
            log("\t/: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1int % val2uint;
            }
            afterTime = getTimer();
            log("\t%: " + (afterTime-beforeTime));
 
            log("\t++: n/a");
 
            log("\t--: n/a");
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1int == val2uint;
            }
            afterTime = getTimer();
            log("\t==: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1int === val2uint;
            }
            afterTime = getTimer();
            log("\t===: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1int != val2uint;
            }
            afterTime = getTimer();
            log("\t!=: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1int !== val2uint;
            }
            afterTime = getTimer();
            log("\t!==: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1int > val2uint;
            }
            afterTime = getTimer();
            log("\t>: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1int >= val2uint;
            }
            afterTime = getTimer();
            log("\t>=: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1int < val2uint;
            }
            afterTime = getTimer();
            log("\t<=: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1int && val2uint;
            }
            afterTime = getTimer();
            log("\t&&: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1int || val2uint;
            }
            afterTime = getTimer();
            log("\t||: " + (afterTime-beforeTime));
 
            log("\t!: n/a");
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1int = val2uint;
            }
            afterTime = getTimer();
            log("\t=: " + (afterTime-beforeTime));
 
            log("number");
            init();
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1number & val2number;
            }
            afterTime = getTimer();
            log("\t&: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1number | val2number;
            }
            afterTime = getTimer();
            log("\t|: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1number ^ val2number;
            }
            afterTime = getTimer();
            log("\t^: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                ~val1number;
            }
            afterTime = getTimer();
            log("\t~: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1number >> val2number;
            }
            afterTime = getTimer();
            log("\t>>: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1number >>> val2number;
            }
            afterTime = getTimer();
            log("\t>>>: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1number << val2number;
            }
            afterTime = getTimer();
            log("\t<<: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1number + val2number;
            }
            afterTime = getTimer();
            log("\t+: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1number - val2number;
            }
            afterTime = getTimer();
            log("\t-: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1number * val2number;
            }
            afterTime = getTimer();
            log("\t*: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1number / val2number;
            }
            afterTime = getTimer();
            log("\t/: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1number % val2number;
            }
            afterTime = getTimer();
            log("\t%: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1number++;
            }
            afterTime = getTimer();
            log("\t++: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1number--;
            }
            afterTime = getTimer();
            log("\t--: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1number == val2number;
            }
            afterTime = getTimer();
            log("\t==: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1number === val2number;
            }
            afterTime = getTimer();
            log("\t===: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1number != val2number;
            }
            afterTime = getTimer();
            log("\t!=: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1number !== val2number;
            }
            afterTime = getTimer();
            log("\t!==: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1number > val2number;
            }
            afterTime = getTimer();
            log("\t>: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1number >= val2number;
            }
            afterTime = getTimer();
            log("\t>=: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1number < val2number;
            }
            afterTime = getTimer();
            log("\t<=: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1number && val2number;
            }
            afterTime = getTimer();
            log("\t&&: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1number || val2number;
            }
            afterTime = getTimer();
            log("\t||: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                !val1number;
            }
            afterTime = getTimer();
            log("\t!: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1number = val2number;
            }
            afterTime = getTimer();
            log("\t=: " + (afterTime-beforeTime));
 
            log("int/number");
            init();
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1int & val2number;
            }
            afterTime = getTimer();
            log("\t&: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1int | val2number;
            }
            afterTime = getTimer();
            log("\t|: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1int ^ val2number;
            }
            afterTime = getTimer();
            log("\t^: " + (afterTime-beforeTime));
 
            log("\t~: n/a");
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1int >> val2number;
            }
            afterTime = getTimer();
            log("\t>>: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1int >>> val2number;
            }
            afterTime = getTimer();
            log("\t>>>: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1int << val2number;
            }
            afterTime = getTimer();
            log("\t<<: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1int + val2number;
            }
            afterTime = getTimer();
            log("\t+: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1int - val2number;
            }
            afterTime = getTimer();
            log("\t-: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1int * val2number;
            }
            afterTime = getTimer();
            log("\t*: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1int / val2number;
            }
            afterTime = getTimer();
            log("\t/: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1int % val2number;
            }
            afterTime = getTimer();
            log("\t%: " + (afterTime-beforeTime));
 
            log("\t++: n/a");
 
            log("\t--: n/a");
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1int == val2number;
            }
            afterTime = getTimer();
            log("\t==: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1int === val2number;
            }
            afterTime = getTimer();
            log("\t===: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1int != val2number;
            }
            afterTime = getTimer();
            log("\t!=: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1int !== val2number;
            }
            afterTime = getTimer();
            log("\t!==: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1int > val2number;
            }
            afterTime = getTimer();
            log("\t>: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1int >= val2number;
            }
            afterTime = getTimer();
            log("\t>=: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1int < val2number;
            }
            afterTime = getTimer();
            log("\t<=: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1int && val2number;
            }
            afterTime = getTimer();
            log("\t&&: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1int || val2number;
            }
            afterTime = getTimer();
            log("\t||: " + (afterTime-beforeTime));
 
            log("\t!: n/a");
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1int = val2number;
            }
            afterTime = getTimer();
            log("\t=: " + (afterTime-beforeTime));
 
            log("uint/number");
            init();
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1uint & val2number;
            }
            afterTime = getTimer();
            log("\t&: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1uint | val2number;
            }
            afterTime = getTimer();
            log("\t|: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1uint ^ val2number;
            }
            afterTime = getTimer();
            log("\t^: " + (afterTime-beforeTime));
 
            log("\t~: n/a");
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1uint >> val2number;
            }
            afterTime = getTimer();
            log("\t>>: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1uint >>> val2number;
            }
            afterTime = getTimer();
            log("\t>>>: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1uint << val2number;
            }
            afterTime = getTimer();
            log("\t<<: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1uint + val2number;
            }
            afterTime = getTimer();
            log("\t+: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1uint - val2number;
            }
            afterTime = getTimer();
            log("\t-: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1uint * val2number;
            }
            afterTime = getTimer();
            log("\t*: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1uint / val2number;
            }
            afterTime = getTimer();
            log("\t/: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1uint % val2number;
            }
            afterTime = getTimer();
            log("\t%: " + (afterTime-beforeTime));
 
            log("\t++: n/a");
 
            log("\t--: n/a");
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1uint == val2number;
            }
            afterTime = getTimer();
            log("\t==: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1uint === val2number;
            }
            afterTime = getTimer();
            log("\t===: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1uint != val2number;
            }
            afterTime = getTimer();
            log("\t!=: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1uint !== val2number;
            }
            afterTime = getTimer();
            log("\t!==: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1uint > val2number;
            }
            afterTime = getTimer();
            log("\t>: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1uint >= val2number;
            }
            afterTime = getTimer();
            log("\t>=: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1uint < val2number;
            }
            afterTime = getTimer();
            log("\t<=: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1uint && val2number;
            }
            afterTime = getTimer();
            log("\t&&: " + (afterTime-beforeTime));
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1uint || val2number;
            }
            afterTime = getTimer();
            log("\t||: " + (afterTime-beforeTime));
 
            log("\t!: n/a");
 
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                val1uint = val2number;
            }
            afterTime = getTimer();
            log("\t=: " + (afterTime-beforeTime));
        }
    }
}

I compiled with MXMLC 4.1 and ran using Flash Player 10.1 on a 2.4 Ghz Intel Core i5 with Mac OS X 10.6. I also tested on a 3.0 Ghz Intel Core 2 Duo with Windows XP and got almost identical results, but for brevity I won’t list them here. Here are the results I got with the Core i5:

Operator int uint int/uint number int/number uint/number
& 143 145 145 148 142 142
| 141 148 144 146 144 145
^ 141 145 143 142 148 141
~ 150 142 n/a 141 n/a n/a
>> 145 143 147 143 144 145
>>> 142 140 146 147 143 141
<< 143 145 142 147 144 142
+ 142 146 142 145 142 140
- 145 141 142 141 146 145
* 147 143 146 142 147 145
/ 144 140 146 144 144 147
% 144 142 142 146 142 139
++ 157 159 n/a 174 n/a n/a
157 155 n/a 170 n/a n/a
== 150 142 149 147 147 145
=== 142 141 147 145 146 146
!= 141 147 143 146 142 142
!== 141 146 143 141 141 142
> 145 152 142 142 140 143
>= 146 145 142 146 146 142
<= 148 142 146 144 144 143
&& 145 150 530 301 527 528
|| 150 154 528 301 505 515
! 146 142 n/a 142 n/a n/a
= 160 156 157 158 302 262

With a couple of exceptions, the above table is extremely uniform. Almost every operator on every type was within a 10% performance range. It’s especially noteworthy that classic optimizations like using shifts instead of multiplication (x << 1 instead of x * 2) or multiplying by the inverse (x *= 0.1 instead of x / 10) don't actually get you any discernable results. Is this the JIT doing optimizations? Is this modern CPU architecture at work? Is this virtual machine overhead dwarfing the benefits? It's hard to tell.

There are those couple of exceptions though:

  • && and || - int and uint are 2x faster than Number and 3.5x faster than mixed types (int/uint, int/Number, uint/Number)
  • = - int/Number and uint/Number are 2x slower than everything else

If you can think of any performance critical code you have that's vulnerable to either of the above, you might have an optimization available to you. Otherwise, the main takeaway from this article is to not worry about which operators you're using. Don't bother making your code harder to read by using shifts instead of multiplication and division or by multiplying when dividing is clearer: you won't gain any performance in the process.