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.