Math.ceil() is a common, mundane function that you likely call all the time. I know I do. If performance gets to be important and you have a Math.ceil() in some inner loop or frequently called function, consider inlining it. Below I’ll show you how and provide a test app showing you just how much CPU time you’ll save.

First of all, you should know how the mathematical ceiling function works. Basically, it just rounds up to the next-highest integer. Since it’s such a simple function, it’s pretty straightforward to implement on our own in AS3, AS2, or JavaScript:

function ceilPositiveOnly(value:Number): Number
{
	return value == int(value) ? value : int(value+1);
}
function ceil(value:Number): Number
{
	return value == int(value) ? value : value >= 0 ? int(value+1) : int(value);
}

In both cases we want to firstly make sure we don’t round up values that are already rounded. Secondly, we want to convert the value to an integer with the int() function, which rounds down, but adjust if need be so it rounds down to the next-highest integer than the input value by simply adding one for positive input values. Here is a little test app to prove that this works:

package
{
	import flash.text.*;
	import flash.utils.*;
	import flash.display.*;
 
	public class MyApp extends Sprite
	{
		private var __logger:TextField;
 
		public function MyApp()
		{
			__logger = new TextField();
			__logger.autoSize = TextFieldAutoSize.LEFT;
			addChild(__logger);
 
			log("Positive only:");
			var value:Number;
			var inlineResult:Number;
			var ceilResult:Number;
			for each (value in [1.1, 2.0])
			{
				inlineResult = value == int(value) ? value : int(value+1);
				ceilResult = Math.ceil(value);
				log("\t" + value + ": " + inlineResult + " == " + ceilResult + ": " + (inlineResult == ceilResult ? "PASS" : "FAIL"));
			}
			log("Positive and negative:");
			for each (value in [1.1, 2.0, -1.1, -2.0])
			{
				inlineResult = value == int(value) ? value : value >= 0 ? int(value+1) : int(value);
				ceilResult = Math.ceil(value);
				log("\t" + value + ": " + inlineResult + " == " + ceilResult + ": " + (inlineResult == ceilResult ? "PASS" : "FAIL"));
			}
		}
 
		private function log(msg:*): void
		{
			__logger.appendText(msg + "\n");
		}
	}
}

And the results are:

Positive only:
	1.1: 2 == 2: PASS
	2: 2 == 2: PASS
Positive and negative:
	1.1: 2 == 2: PASS
	2: 2 == 2: PASS
	-1.1: -1 == -1: PASS
	-2: -2 == -2: PASS

Now for an app to test the speed of inlining our AS3 version of Math.ceil():

package
{
	import flash.text.*;
	import flash.utils.*;
	import flash.display.*;
 
	public class MyApp extends Sprite
	{
		private var __logger:TextField;
 
		public function MyApp()
		{
			__logger = new TextField();
			__logger.autoSize = TextFieldAutoSize.LEFT;
			addChild(__logger);
 
			const ITERATIONS:int = 50000000;
			var i:int;
			var res:Number;
			var before:int = getTimer();
			var value:Number = 0.0;
			for (i = 0; i < ITERATIONS; ++i)
			{
				res = value == int(value) ? value : int(value+1);
				value += 1.0;
			}
			log("Inline (positive only): " + (getTimer()-before));
 
			before = getTimer();
			value = 0.0;
			for (i = 0; i < ITERATIONS; ++i)
			{
				res = value == int(value) ? value : value >= 0 ? int(value+1) : int(value);
				value += 1.0;
			}
			log("Inline (positive and negative): " + (getTimer()-before));
 
			before = getTimer();
			value = 0.0;
			for (i = 0; i < ITERATIONS; ++i)
			{
				res = Math.ceil(value);
				value += 1.0;
			}
			log("Math.ceil(): " + (getTimer()-before));
		}
 
		private function log(msg:*): void
		{
			__logger.appendText(msg + "\n");
		}
	}
}

My results on a 2.2 Ghz Intel Core 2 Duo CPU with 2GB RAM on Mac OS X 10.6 are:

Inline (positive only): 479
Inline (positive and negative): 478
Math.ceil(): 3234

Oddly enough, the version supporting negative values seems a hair faster throughout many repetitions of this test. I haven’t yet seen it perform slower than the positive-only version, even though the test only checked positive values so as to have a straight comparison. I therefore don’t see much reason to use the positive-only version other than minor quibbles about readability and code size.

So there you have it. This is a vastly faster (6.76x in AS3) faster way to go about finding the ceiling of numbers in AS3, AS2, and JavaScript. Remember this you find yourself doing something performance critical with a Math.ceil()!