Runtime performance Android vs. Iphonea
Apr 26, 2012 12:00 PM
Tags: none (add) #air #iphone #android #ios #performance #benchmarkI have converted a benchmark to AS3 to measure some performance properties of AIR 3.2 on iPhone and Android devices. Next to that, I used the same benchmark in a Javascript page to get an idea about the performance in relationship to other software.
On Android, the devices perform differently well, but in general, AIR is about 1.5-3 times faster than the JS test and also faster than the Java implementation I wrote (which is remarkebly). For iOS, it is however exactly reversed. The test executes in about 30-100 ms on android devices, the same test takes over 500 ms on the iPhone4 (it is not running in the interpreter mode - that would be way worse).
Is there anything that I could improve (I am wondering if there's a compiler flag / some mistake I am doing)? I only made this test after the software I am working on performed really bad on iOS and the benchmark confirms that I am dealing with a problem related to computation speed. The problem is, that the slowdown of factor 5 is quite huge, and other operations seem to be also much slower than this benchmark.
These are the numbers I have found:
| device | javascript | flash | java / obj. c |
| PC | 22 | 107 | |
| Asus transformer prime | 77 | 33 | 56 |
| Samsung Note | 107 | 28 | 77 |
| Nexus S | 153 | 120 | 155 |
| Flash Galaxy Tab | 160 | 45 | 63 |
| Iphone 4 | 309 | 500 | |
| htc desire s | 423 | 62 | 89 |
| Iphone 3 | 424 | 680 | |
| Samsung GT-S5830 | 1076 | n/a | 380 |
And here's the code in question (it's converted from http://shootout.alioth.debian.org/u32/program.php?test=nbody&lang=v8&i d=1)
package de.innogames.benchmark
{
import flash.display.Sprite;
import flash.events.Event;
import flash.text.TextField;
import flash.utils.getTimer;
public class BenchNBody extends Sprite
{
public static const PI: Number = 3.141592653589793;
public static const DAYS_PER_YEAR:Number = 365.24;
public static const SOLAR_MASS:Number = 4 * PI * PI;
public var bodies: Vector.<Body>;
public function BenchNBody()
{
addEventListener(Event.ENTER_FRAME, onRender);
tf = new TextField();
}
private var n:int = 0;
private var tf:TextField;
private function onRender(e:Event):void {
if (n++ % 30 == 0) {
run(10000);
}
}
public function run(n:int):void {
var tstart: int = getTimer();
this.bodies = Vector.<Body>([Sun(),Jupiter(),Saturn(),Uranus(),Neptune()]);
var px:Number = 0.0;
var py:Number = 0.0;
var pz:Number = 0.0;
var size:int = this.bodies.length;
for (var i:int=0; i<size; i++){
var b:Body = bodies[i];
var m:Number = b.mass;
px += b.vx * m;
py += b.vy * m;
pz += b.vz * m;
}
bodies[0].offsetMomentum(px, py, pz);
//trace(energy().toFixed(9));
for (i=0; i<n; i++){ advance(0.01); }
//trace(energy().toFixed(9));
tstart = getTimer() - tstart;
tf.text = tstart+"";
addChild(tf);
}
public function advance (dt: Number): void {
var dx:Number, dy:Number, dz:Number, distance:Number, mag:Number;
var size:int = this.bodies.length;
for (var i:int=0; i<size; i++) {
var bodyi:Body = this.bodies[i];
for (var j:int=i+1; j<size; j++) {
var bodyj:Body = this.bodies[j];
dx = bodyi.x - bodyj.x;
dy = bodyi.y - bodyj.y;
dz = bodyi.z - bodyj.z;
distance = Math.sqrt(dx*dx + dy*dy + dz*dz);
mag = dt / (distance * distance * distance);
bodyi.vx -= dx * bodyj.mass * mag;
bodyi.vy -= dy * bodyj.mass * mag;
bodyi.vz -= dz * bodyj.mass * mag;
bodyj.vx += dx * bodyi.mass * mag;
bodyj.vy += dy * bodyi.mass * mag;
bodyj.vz += dz * bodyi.mass * mag;
}
}
for (i=0; i<size; i++) {
var body:Body = this.bodies[i];
body.x += dt * body.vx;
body.y += dt * body.vy;
body.z += dt * body.vz;
}
}
public function energy (): Number {
var dx:Number, dy:Number, dz:Number, distance:Number;
var e:Number = 0.0;
var size:int = this.bodies.length;
for (var i:int=0; i<size; i++) {
var bodyi:Body = this.bodies[i];
e += 0.5 * bodyi.mass *
( bodyi.vx * bodyi.vx
+ bodyi.vy * bodyi.vy
+ bodyi.vz * bodyi.vz );
for (var j:int=i+1; j<size; j++) {
var bodyj:Body = this.bodies[j];
dx = bodyi.x - bodyj.x;
dy = bodyi.y - bodyj.y;
dz = bodyi.z - bodyj.z;
distance = Math.sqrt(dx*dx + dy*dy + dz*dz);
e -= (bodyi.mass * bodyj.mass) / distance;
}
}
return e;
}
public static function Jupiter():Body {
return new Body(
4.84143144246472090e+00,
-1.16032004402742839e+00,
-1.03622044471123109e-01,
1.66007664274403694e-03 * DAYS_PER_YEAR,
7.69901118419740425e-03 * DAYS_PER_YEAR,
-6.90460016972063023e-05 * DAYS_PER_YEAR,
9.54791938424326609e-04 * SOLAR_MASS
);
}
public static function Saturn(): Body{
return new Body(
8.34336671824457987e+00,
4.12479856412430479e+00,
-4.03523417114321381e-01,
-2.76742510726862411e-03 * DAYS_PER_YEAR,
4.99852801234917238e-03 * DAYS_PER_YEAR,
2.30417297573763929e-05 * DAYS_PER_YEAR,
2.85885980666130812e-04 * SOLAR_MASS
);
}
public static function Uranus(): Body{
return new Body(
1.28943695621391310e+01,
-1.51111514016986312e+01,
-2.23307578892655734e-01,
2.96460137564761618e-03 * DAYS_PER_YEAR,
2.37847173959480950e-03 * DAYS_PER_YEAR,
-2.96589568540237556e-05 * DAYS_PER_YEAR,
4.36624404335156298e-05 * SOLAR_MASS
);
}
public static function Neptune():Body{
return new Body(
1.53796971148509165e+01,
-2.59193146099879641e+01,
1.79258772950371181e-01,
2.68067772490389322e-03 * DAYS_PER_YEAR,
1.62824170038242295e-03 * DAYS_PER_YEAR,
-9.51592254519715870e-05 * DAYS_PER_YEAR,
5.15138902046611451e-05 * SOLAR_MASS
);
}
public static function Sun():Body{
return new Body(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, SOLAR_MASS);
}
}
}
And here's the second file...
package de.innogames.benchmark
{
internal class Body {
public var x: Number;
public var y: Number;
public var z: Number;
public var vx: Number;
public var vy: Number;
public var vz: Number;
public var mass: Number;
public function Body (x:Number,y:Number,z:Number,vx:Number,vy:Number,vz:Number,mass:Number ) {
this.x = x;
this.y = y;
this.z = z;
this.mass = mass;
this.vx = vx;
this.vy = vy;
this.vz = vz;
}
public function offsetMomentum (px:Number,py:Number,pz:Number):Body {
this.vx = -px / BenchNBody.SOLAR_MASS;
this.vy = -py / BenchNBody.SOLAR_MASS;
this.vz = -pz / BenchNBody.SOLAR_MASS;
return this;
}
}
}



