package {
/**
* Number type testing in Actionscript 3.0
* James L. Gauthier Nov. 2007
* Please post comments to www.jlGauthier.com/blog
*/
import flash.display.Sprite;
import flash.display.StageScaleMode;
import flash.events.Event;
import flash.text.TextField;
import flash.utils.getTimer;
import flash.system.Capabilities;
public class NumberTypes extends Sprite{
/**
* The purpose of this class is benchmark a collection of opperations
* on each of the number types with-in AS3. By providing a method
* for collecting data on different configurations and machines.
*
* Because of the expected performance variance across machines
* bench marks are reported in a unit equivilent to one function call.
* A score of 0.02 means the opperation performed 50 times
* equates to a single function call.
*/
function NumberTypes(){
stage.scaleMode=StageScaleMode.NO_SCALE;
stage.align='TL';
addChild(_tf);
_tf.height=800
_tf.background=true;
_tf.backgroundColor=0xffffff;
_tf.width=260;
_tf.multiline=true;
_tf.wordWrap=true;
_out(Capabilities.isDebugger?' Debug Development Player\n' : 'Public Player\n');
_out('['+Capabilities.manufacturer+', '+Capabilities.os+']\n');
_out('['+Capabilities.playerType+', '+Capabilities.version+']\n');
_tests.push(_functionCall);
_tests.push(_arrayIndexing);
_tests.push(_additionUint);
_tests.push(_additionInt);
_tests.push(_additionNumber);
_tests.push(_subtractionUint);
_tests.push(_subtractionInt);
_tests.push(_subtractionNumber);
_tests.push(_addition2);
_tests.push(_subtraction2);
_tests.push(_binaryOps);
_tests.push(_modulus);
_tests.push(_division);
_tests.push(_multiplcation);
_tests.push(_multiplcation2);
_tests.push(_assignToUint);
_tests.push(_assignToInt);
_tests.push(_assignToNumber);
_tests.push(_assignToNumber2);
_tests.push(_compareToUint);
_tests.push(_compareToInt);
_tests.push(_compareToNumber);
_tests.push(_convertToUint);
_tests.push(_convertToInt);
_tests.push(_convertToNumber);
_tests.push(_forLoop);
_tests.push(_whileLoop);
addEventListener(Event.ENTER_FRAME,_nextTest);
}
/**
* performs 1 test per frame until the _tests queue
* is empty.
*/
private function _nextTest(evt:*=null):void{
if(_tests.length==0){
removeEventListener(Event.ENTER_FRAME,_nextTest);
_out('Complete.\n');
return;
}
_tests.shift()();
}
/**
* Each test contains 5 marks. Each mark is stored here
* when 5 marks are collected this method outputs the
* result of the test.
*/
private function _mark():void{
_marks[_markIndex]=getTimer();
_markIndex++;
if(_markIndex==5){
var baseTime:int=_marks[1]-_marks[0];
var uintTime:int=_marks[2]-_marks[1]-baseTime;
var intTime:int=_marks[3]-_marks[2]-baseTime;
var numberTime:int=_marks[4]-_marks[3]-baseTime;
_out('uint: '+_format(uintTime)+' int: '+_format(intTime)+' number: ' +_format(numberTime)+'\n');
_markIndex=0;
}
}
/**
* Convers milisecond time to function time.
* And performs simple formatting.
*/
private function _format(n:int):String{
var score:Number=n/_unit;
var base:int = score|0;
var dec:Number=score-base;
var decString:String=String(dec*1000).split('.')[0];
while(decString.length<3){
decString='0'+decString;
}
return String(base)+'.'+decString;
}
/**
* Places a string in the output textbox
*/
private function _out(str:String):void{
_tf.appendText(str);
}
/**
* Sets the unit by wich all other tests are
* measured.
*/
private function _functionCall():void{
var i:uint=0, t2:int=0, t1:int=0, t0:int=getTimer();
for(i=0;i<_testScale; i++){
}
t1=getTimer();
for(i=0;i<_testScale;i++){
__test1();
}
t2=getTimer();
_unit=(t2-t1)-(t1-t0)
_out('function call time: '+(_unit)+'\n');
}
/**
* Empty private function. This is the testing unit.
*/
private function __test1():void{
}
private function _arrayIndexing():void{
_out('Array[Index]\n');
var i:uint=0;
var typeUint:uint=55;
var typeInt:int=55;
var typeNumber:Number=55;
var accessArray:Array=[];
var len:uint=56;
while(len--){
accessArray[len]=0;
}
_mark();
for(i=0;i<_testScale;i++){
}
_mark();
for(i=0;i<_testScale;i++){
accessArray[typeUint];
}
_mark();
for(i=0;i<_testScale;i++){
accessArray[typeInt];
}
_mark();
for(i=0;i<_testScale;i++){
accessArray[typeNumber];
}
_mark();
}
private function _additionUint():void{
_out('Addition += uint\n');
var i:uint=0;
var typeUint:uint=55;
var typeInt:int=55;
var typeNumber:Number=55;
var test:uint=5;
_mark();
for(i=0;i<_testScale;i++){
}
_mark();
for(i=0;i<_testScale;i++){
typeUint+=test;
}
_mark();
for(i=0;i<_testScale;i++){
typeInt+=test;
}
_mark();
for(i=0;i<_testScale;i++){
typeNumber+=test;
}
_mark();
}
private function _additionInt():void{
_out('Addition += int\n');
var i:uint=0;
var typeUint:uint=55;
var typeInt:int=55;
var typeNumber:Number=55;
var test:int=5;
_mark();
for(i=0;i<_testScale;i++){
}
_mark();
for(i=0;i<_testScale;i++){
typeUint+=test;
}
_mark();
for(i=0;i<_testScale;i++){
typeInt+=test;
}
_mark();
for(i=0;i<_testScale;i++){
typeNumber+=test;
}
_mark();
}
private function _additionNumber():void{
_out('Addition += Number\n');
var i:uint=0;
var typeUint:uint=55;
var typeInt:int=55;
var typeNumber:Number=55;
var test:Number=5;
_mark();
for(i=0;i<_testScale;i++){
}
_mark();
for(i=0;i<_testScale;i++){
typeUint+=test;
}
_mark();
for(i=0;i<_testScale;i++){
typeInt+=test;
}
_mark();
for(i=0;i<_testScale;i++){
typeNumber+=test;
}
_mark();
}
private function _addition2():void{
_out('Addition + 5\n');
var i:uint=0;
var typeUint:uint=55;
var typeInt:int=55;
var typeNumber:Number=55;
_mark();
for(i=0;i<_testScale;i++){
}
_mark();
for(i=0;i<_testScale;i++){
typeUint+=5;
}
_mark();
for(i=0;i<_testScale;i++){
typeInt+=5;
}
_mark();
for(i=0;i<_testScale;i++){
typeNumber+=5;
}
_mark();
}
private function _subtractionUint():void{
_out('subtraction -= uint\n');
var i:uint=0;
var typeUint:uint=_testScale*5;
var typeInt:int=_testScale*5;
var typeNumber:Number=_testScale*5;
var test:uint=5;
_mark();
for(i=0;i<_testScale;i++){
}
_mark();
for(i=0;i<_testScale;i++){
typeUint-=test;
}
_mark();
for(i=0;i<_testScale;i++){
typeInt-=test;
}
_mark();
for(i=0;i<_testScale;i++){
typeNumber-=test;
}
_mark();
}
private function _subtractionInt():void{
_out('subtraction -= int\n');
var i:uint=0;
var typeUint:uint=_testScale*5;
var typeInt:int=_testScale*5;
var typeNumber:Number=_testScale*5;
var test:int=5;
_mark();
for(i=0;i<_testScale;i++){
}
_mark();
for(i=0;i<_testScale;i++){
typeUint-=test;
}
_mark();
for(i=0;i<_testScale;i++){
typeInt-=test;
}
_mark();
for(i=0;i<_testScale;i++){
typeNumber-=test;
}
_mark();
}
private function _subtractionNumber():void{
_out('subtraction -= Number\n');
var i:uint=0;
var typeUint:uint=_testScale*5;
var typeInt:int=_testScale*5;
var typeNumber:Number=_testScale*5;
var test:Number=5;
_mark();
for(i=0;i<_testScale;i++){
}
_mark();
for(i=0;i<_testScale;i++){
typeUint-=test;
}
_mark();
for(i=0;i<_testScale;i++){
typeInt-=test;
}
_mark();
for(i=0;i<_testScale;i++){
typeNumber-=test;
}
_mark();
}
private function _subtraction2():void{
_out('Subtraction - 5\n');
var i:uint=1;
var typeUint:uint=_testScale*5;
var typeInt:int=_testScale*5;
var typeNumber:Number=_testScale*5;
_mark();
for(i=0;i<_testScale;i++){
}
_mark();
for(i=0;i<_testScale;i++){
typeUint-=5;
}
_mark();
for(i=0;i<_testScale;i++){
typeInt-=5;
}
_mark();
for(i=0;i<_testScale;i++){
typeNumber-=5;
}
_mark();
}
private function _binaryOps():void{
_out('Bin&ry Op\n');
var i:uint=0;
var typeUint:uint=55;
var typeInt:int=55;
var typeNumber:Number=55;
_mark();
for(i=0;i<_testScale;i++){
}
_mark();
for(i=0;i<_testScale;i++){
typeUint=(typeUint<<2)&0xff;
}
_mark();
for(i=0;i<_testScale;i++){
typeInt=(typeInt<<2)&0xff;
}
_mark();
for(i=0;i<_testScale;i++){
typeNumber=(typeNumber<<2)&0xff;
}
_mark();
}
private function _division():void{
_out('Di/ision\n');
var i:uint=0;
var typeUint:uint=55;
var typeInt:int=55;
var typeNumber:Number=55;
var typeUint2:uint=55;
var typeInt2:int=55;
var typeNumber2:Number=55;
_mark();
for(i=0;i<_testScale;i++){
}
_mark();
for(i=0;i<_testScale;i++){
typeUint=typeUint2/5;
}
_mark();
for(i=0;i<_testScale;i++){
typeInt=typeInt2/5;
}
_mark();
for(i=0;i<_testScale;i++){
typeNumber=typeNumber2/5;
}
_mark();
}
private function _modulus():void{
_out('M%dulus\n');
var i:uint=0;
var typeUint:uint=55;
var typeInt:int=55;
var typeNumber:Number=55;
var typeUint2:uint=55;
var typeInt2:int=55;
var typeNumber2:Number=55;
_mark();
for(i=0;i<_testScale;i++){
}
_mark();
for(i=0;i<_testScale;i++){
typeUint=typeUint2%5;
}
_mark();
for(i=0;i<_testScale;i++){
typeInt=typeInt2%5;
}
_mark();
for(i=0;i<_testScale;i++){
typeNumber=typeNumber2%5;
}
_mark();
}
private function _multiplcation():void{
_out('Multiplication * 5\n');
var i:uint=0;
var typeUint:uint=55;
var typeInt:int=55;
var typeNumber:Number=55;
var typeUint2:uint=55;
var typeInt2:int=55;
var typeNumber2:Number=55;
_mark();
for(i=0;i<_testScale;i++){
}
_mark();
for(i=0;i<_testScale;i++){
typeUint=typeUint2*5;
}
_mark();
for(i=0;i<_testScale;i++){
typeInt=typeInt2*5;
}
_mark();
for(i=0;i<_testScale;i++){
typeNumber=typeNumber2*5;
}
_mark();
}
private function _multiplcation2():void{
_out('Multiplication * .5\n');
var i:uint=0;
var typeUint:uint=55;
var typeInt:int=55;
var typeNumber:Number=55;
_mark();
for(i=0;i<_testScale;i++){
}
_mark();
for(i=0;i<_testScale;i++){
typeUint*=.5;
}
_mark();
for(i=0;i<_testScale;i++){
typeInt*=.5;
}
_mark();
for(i=0;i<_testScale;i++){
typeNumber*=.5;
}
_mark();
}
private function _assignToUint():void{
_out('Assingment=uint\n');
var i:uint=0;
var typeUint:uint=55;
var typeInt:int=55;
var typeNumber:Number=55;
var value:uint=56;
_mark();
for(i=0;i<_testScale;i++){
}
_mark();
for(i=0;i<_testScale;i++){
typeUint=value;
}
_mark();
for(i=0;i<_testScale;i++){
typeInt=value;
}
_mark();
for(i=0;i<_testScale;i++){
typeNumber=value;
}
_mark();
}
private function _assignToInt():void{
_out('Assingment=int\n');
var i:uint=0;
var typeUint:uint=55;
var typeInt:int=55;
var typeNumber:Number=55;
var value:int=56;
_mark();
for(i=0;i<_testScale;i++){
}
_mark();
for(i=0;i<_testScale;i++){
typeUint=value;
}
_mark();
for(i=0;i<_testScale;i++){
typeInt=value;
}
_mark();
for(i=0;i<_testScale;i++){
typeNumber=value;
}
_mark();
}
private function _assignToNumber():void{
_out('Assingment=Number 56\n');
var i:uint=0;
var typeUint:uint=55;
var typeInt:int=55;
var typeNumber:Number=55;
var value:Number=56;
_mark();
for(i=0;i<_testScale;i++){
}
_mark();
for(i=0;i<_testScale;i++){
typeUint=value;
}
_mark();
for(i=0;i<_testScale;i++){
typeInt=value;
}
_mark();
for(i=0;i<_testScale;i++){
typeNumber=value;
}
_mark();
}
private function _assignToNumber2():void{
_out('Assingment=Number 5.6\n');
var i:uint=0;
var typeUint:uint=55;
var typeInt:int=55;
var typeNumber:Number=55;
var value:Number=5.6;
_mark();
for(i=0;i<_testScale;i++){
}
_mark();
for(i=0;i<_testScale;i++){
typeUint=value;
}
_mark();
for(i=0;i<_testScale;i++){
typeInt=value;
}
_mark();
for(i=0;i<_testScale;i++){
typeNumber=value;
}
_mark();
}
private function _compareToUint():void{
_out('Compare==uint\n');
var i:uint=0;
var typeUint:uint=55;
var typeInt:int=55;
var typeNumber:Number=55;
var value:uint=56;
_mark();
for(i=0;i<_testScale;i++){
}
_mark();
for(i=0;i<_testScale;i++){
typeUint===value;
}
_mark();
for(i=0;i<_testScale;i++){
typeInt===value;
}
_mark();
for(i=0;i<_testScale;i++){
typeNumber===value;
}
_mark();
}
private function _compareToInt():void{
_out('Compare==int\n');
var i:uint=0;
var typeUint:uint=55;
var typeInt:int=55;
var typeNumber:Number=55;
var value:int=56;
_mark();
for(i=0;i<_testScale;i++){
}
_mark();
for(i=0;i<_testScale;i++){
typeUint==value;
}
_mark();
for(i=0;i<_testScale;i++){
typeInt==value;
}
_mark();
for(i=0;i<_testScale;i++){
typeNumber==value;
}
_mark();
}
private function _compareToNumber():void{
_out('Compare==Number\n');
var i:uint=0;
var typeUint:uint=55;
var typeInt:int=55;
var typeNumber:Number=55;
var value:Number=56;
_mark();
for(i=0;i<_testScale;i++){
}
_mark();
for(i=0;i<_testScale;i++){
typeUint==value;
}
_mark();
for(i=0;i<_testScale;i++){
typeInt==value;
}
_mark();
for(i=0;i<_testScale;i++){
typeNumber==value;
}
_mark();
}
private function _convertToUint():void{
_out('uint(convert)\n');
var i:uint=0;
var typeUint:uint=55;
var typeInt:int=55;
var typeNumber:Number=55;
var value:uint=56;
_mark();
for(i=0;i<_testScale;i++){
}
_mark();
for(i=0;i<_testScale;i++){
value=uint(typeUint);
}
_mark();
for(i=0;i<_testScale;i++){
value=uint(typeInt);
}
_mark();
for(i=0;i<_testScale;i++){
value=uint(typeNumber);
}
_mark();
}
private function _convertToInt():void{
_out('int(convert)\n');
var i:uint=0;
var typeUint:uint=55;
var typeInt:int=55;
var typeNumber:Number=55;
var value:int=56;
_mark();
for(i=0;i<_testScale;i++){
}
_mark();
for(i=0;i<_testScale;i++){
value=int(typeUint);
}
_mark();
for(i=0;i<_testScale;i++){
value=int(typeInt);
}
_mark();
for(i=0;i<_testScale;i++){
value=int(typeNumber);
}
_mark();
}
private function _convertToNumber():void{
_out('Number(convert)\n');
var i:uint=0;
var typeUint:uint=55;
var typeInt:int=55;
var typeNumber:Number=55;
var value:Number=56.335;
_mark();
for(i=0;i<_testScale;i++){
}
_mark();
for(i=0;i<_testScale;i++){
value=Number(typeUint);
}
_mark();
for(i=0;i<_testScale;i++){
value=Number(typeInt);
}
_mark();
for(i=0;i<_testScale;i++){
value=Number(typeNumber);
}
_mark();
}
private function _forLoop():void{
_out('For (<loop++)\n');
var typeUint:uint=0;
var typeInt:int=0;
var typeNumber:Number=0;
var limitUint:uint=_testScale;
var limitInt:int=_testScale;
var limitNumber:Number=_testScale;
var value:Number=56;
_mark();
_mark();
for(typeUint;typeUint<limitUint;typeUint++){
}
_mark();
for(typeInt;typeInt<limitInt;typeInt++){
}
_mark();
for(typeNumber;typeNumber<limitNumber;typeNumber++){
}
_mark();
}
private function _whileLoop():void{
_out('while (loop--)\n');
var limitUint:uint=_testScale;
var limitInt:int=_testScale;
var limitNumber:Number=_testScale;
var value:Number=56;
_mark();
_mark();
while(limitUint--){
}
_mark();
while(limitInt--){
}
_mark();
while(limitNumber--){
}
_mark();
}
private const _tests:Array=new Array();
private const _marks:Array=new Array(5);
private var _markIndex:uint=0;
private var _unit:int=0;
private const _tf:TextField = new TextField();
private const _testScale:uint=10000000;
}
}