Stable performance test on if/else variants for 20 options
Testing the performance of basic language structures is difficult. This test runs continuously many operations on a complex if/else construct with 20 options for various checks. The running over time ensures the stability of the result
ActionScript3 source code
/**
* Copyright leichtgewicht ( http://wonderfl.net/user/leichtgewicht )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/cllu
*/
package {
import flash.display.AVM1Movie;
import flash.utils.setTimeout;
import flash.events.Event;
import flash.utils.getTimer;
import flash.text.TextField;
import flash.display.Sprite;
public class FlashTest extends Sprite {
private var _text:TextField = new TextField;
private var _dataSets: Array = [
[1], // Just the first entry
[1,2,3], // the first three
[9,10,11], // the middle three
[3,11,17], // some three
[18,19,20], // end three
[20], // Just the last entry
[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20] // all
];
private var _operations: Array = [ {
name: 'byte if/else',
op: testByte
}, {
name: 'byte if/else (reduced)',
op: testByteReduced
}, {
name: 'binary if/else',
op: testBinary
}, {
name: 'binary if/else (reduced)',
op: testBinaryReduced
}, {
name: 'balanced if/else',
op: testBalanced
}, {
name: 'balanced if/else (reduced)',
op: testBalancedReduced
}, {
name: 'linear if/elseif',
op: testLinear
}, {
name: 'switch',
op: testSwitch
} ];
private var _count: int = 5000000;
private var _run: int = 0;
private var _current: int = 0;
private var _tMax: Number;
private var _data: Object = {};
public function FlashTest() {
addChild( _text );
_text.width = stage.stageWidth;
_text.height = stage.stageHeight;
stage.frameRate = 5;
_tMax = int(1000/stage.frameRate * 0.5); // Maximal 50% load
for each( var op: Object in _operations) {
op.run = 0;
op.avg = 0;
op.max = 0;
op.min = int.MAX_VALUE;
}
testRun();
}
public function testRun():void {
var result: Object = {}, tTotal: Number = 0.0, i:int;
while( true ) {
var op: Object = _operations[_current++];
var dataNo: int = op.run%_dataSets.length;
var data: Vector.<int>;
if( _data[dataNo] ) {
data = _data[dataNo];
} else {
var dataSet: Array = _dataSets[dataNo];
var dataSetLen: int = dataSet.length;
data = new Vector.<int>(_count);
for( i=0; i<_count; ++i){
data[i] = dataSet[i%dataSetLen];
}
_data[dataNo] = data;
}
var t: Number = getTimer();
op.op(data, _count);
t = getTimer()-t;
op.min = op.min > t ? t : op.min;
op.avg = int((op.avg*op.run+t)/(++op.run)*100.0)/100.0;
op.max = op.max < t ? t : op.max;
tTotal += t;
if( _current == _operations.length) {
_current = 0;
}
if( tTotal > _tMax ) {
break;
}
}
var min: Number = _operations[0].avg;
_text.text = "";
for( i=0; i<_operations.length; ++i) {
op = _operations[i];
trace(int(100.0/min*op.avg*100.0)/100.0, "% | ",op.min,"ms/", op.avg, "ms/", op.max, "ms for ", op.name, " ("+ op.run+" runs)");
}
trace( "\n"+ _count + " operations");
++_run;
if( _run < int.MAX_VALUE ) {
setTimeout(testRun, 80);
}
}
private function trace(...args:Array):void {
for each( var arg: * in args ) {
if( arg is Number ) {
if( arg is int ) {
arg = arg+".00";
} else {
arg = arg.toString(10);
if( arg.indexOf(".") == arg.length-2 ) {
arg += "0";
}
}
}
_text.appendText(arg);
}
_text.appendText("\n");
}
private function testSwitch(data:Vector.<int>, c:int): void {
var x: int;
for( var i:int = 0; i<c; ++i) {
x = data[i];
switch(x) {
case 1: break;
case 2: break;
case 3: break;
case 4: break;
case 5: break;
case 6: break;
case 7: break;
case 8: break;
case 9: break;
case 10: break;
case 11: break;
case 12: break;
case 13: break;
case 14: break;
case 15: break;
case 16: break;
case 17: break;
case 18: break;
case 19: break;
default:break;
}
}
}
private function testLinear(data:Vector.<int>, c:int): void {
var x: int;
for( var i:int = 0; i<c; ++i) {
x = data[i];
if(x==1) {}
else if(x==2) {}
else if(x==3) {}
else if(x==4) {}
else if(x==5) {}
else if(x==6) {}
else if(x==7) {}
else if(x==8) {}
else if(x==9) {}
else if(x==10) {}
else if(x==11) {}
else if(x==12) {}
else if(x==13) {}
else if(x==14) {}
else if(x==15) {}
else if(x==16) {}
else if(x==17) {}
else if(x==18) {}
else if(x==19) {}
else {}
}
}
private function testBalancedReduced(data:Vector.<int>, c:int): void {
var x: int;
for( var i:int = 0; i<c; ++i) {
x = data[i];
if(x<13) {
if(x<9) {
if(x<5) {
if(x<3) {
if(x==1) {
} else { // 2
}
} else if(x==3) {
} else { // 4
}
} else {
if(x<7) {
if(x==5) {
} else { // 6
}
} else if(x==7) {
} else { // 8
}
}
} else {
if(x<11) {
if(x==9) {
} else { // 10
}
} else if(x==11) {
} else { // 12
}
}
} else {
if(x<17) {
if(x<15) {
if(x==13) {
} else { // 14
}
} else if(x==15) {
} else { // 16
}
} else {
if(x<19) {
if(x==17) {
} else { //18
}
} else if(x==19) {
} else { //20
}
}
}
}
}
private function testBalanced(data:Vector.<int>, c:int): void {
var x: int;
for( var i:int = 0; i<c; ++i) {
x = data[i];
if(x<13) {
if(x<9) {
if(x<5) {
if(x<3) {
if(x==1) {
} else { // 2
}
} else {
if(x==3) {
} else { // 4
}
}
} else {
if(x<7) {
if(x==5) {
} else { // 6
}
} else {
if(x==7) {
} else { // 8
}
}
}
} else {
if(x<11) {
if(x==9) {
} else { // 10
}
} else {
if(x==11) {
} else { // 12
}
}
}
} else {
if(x<17) {
if(x<15) {
if(x==13) {
} else { // 14
}
} else {
if(x==15) {
} else { // 16
}
}
} else {
if(x<19) {
if(x==17) {
} else { //18
}
} else {
if(x==19) {
} else { //20
}
}
}
}
}
}
private function testBinary(data:Vector.<int>, c:int): void {
var x: int;
for( var i:int = 0; i<c; ++i) {
x = data[i];
if(x<17) {
if(x<9) {
if(x<5) {
if(x<3) {
if(x==1) {
} else { // 2
}
} else {
if(x==3) {
} else { // 4
}
}
} else {
if(x<7) {
if(x==5) {
} else { // 6
}
} else {
if(x==7) {
} else { // 8
}
}
}
} else {
if(x<13) {
if(x<11) {
if(x==9) {
} else { // 10
}
} else {
if(x==11) {
} else { // 12
}
}
} else {
if(x<15) {
if(x==13) {
} else { // 14
}
} else {
if(x==15) {
} else { // 16
}
}
}
}
} else {
if(x<19) {
if(x==17) {
} else { //18
}
} else {
if(x==19) {
} else { //20
}
}
}
}
}
private function testBinaryReduced(data:Vector.<int>, c:int): void {
var x: int;
for( var i:int = 0; i<c; ++i) {
x = data[i];
if(x<17) {
if(x<9) {
if(x<5) {
if(x<3) {
if(x==1) {
} else { // 2
}
} else if(x==3) {
} else { // 4
}
} else {
if(x<7) {
if(x==5) {
} else { // 6
}
} else if(x==7) {
} else { // 8
}
}
} else {
if(x<13) {
if(x<11) {
if(x==9) {
} else { // 10
}
} else if(x==11) {
} else { // 12
}
} else {
if(x<15) {
if(x==13) {
} else { // 14
}
} else if(x==15) {
} else { // 16
}
}
}
} else {
if(x<19) {
if(x==17) {
} else { //18
}
} else if(x==19) {
} else { //20
}
}
}
}
private function testByte(data:Vector.<int>, c:int): void {
var x: int;
for( var i:int = 0; i<c; ++i) {
x = data[i];
if(x&1) {
if(x&2) {
if(x&4) {
if(x&8) {
// 15
} else {
// 7
}
} else {
if(x&8) {
// 11
} else {
if(x&16){
// 19
} else {
// 3
}
}
}
} else {
if(x&4) {
if(x&8) {
// 13
} else {
// 5
}
} else {
if(x&8) {
// 9
} else {
if(x&16) {
// 17
} else {
// 1
}
}
}
}
} else {
if(x&2) {
if(x&4) {
if(x&8) {
// 14
} else {
// 6
}
} else {
if(x&8) {
// 10
} else {
if(x&16) {
// 18
} else {
// 16
}
}
}
} else {
if(x&4) {
if(x&8) {
// 12
} else {
if(x&16) {
// 20
} else {
// 4
}
}
} else {
if(x&8) {
// 8
} else {
// 16
}
}
}
}
}
}
private function testByteReduced(data:Vector.<int>, c:int): void {
var x: int;
for( var i:int = 0; i<c; ++i) {
x = data[i];
if(x&1) {
if(x&2) {
if(x&4) {
if(x&8) {
// 15
} else {
// 7
}
} else {
if(x&8) {
// 11
} else if(x&16){
// 19
} else {
// 3
}
}
} else {
if(x&4) {
if(x&8) {
// 13
} else {
// 5
}
} else {
if(x&8) {
// 9
} else if(x&16) {
// 17
} else {
// 1
}
}
}
} else {
if(x&2) {
if(x&4) {
if(x&8) {
// 14
} else {
// 6
}
} else {
if(x&8) {
// 10
} else if(x&16) {
// 18
} else {
// 16
}
}
} else {
if(x&4) {
if(x&8) {
// 12
} else if(x&16) {
// 20
} else {
// 4
}
} else if(x&8) {
// 8
} else {
// 16
}
}
}
}
}
}
}