1 Reply Latest reply on Apr 26, 2012 3:26 PM by chris.campbell

    Runtime performance Android vs. Iphonea

    zet23t

      I 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:

      devicejavascriptflashjava / obj. c
      PC22107
      Asus transformer prime773356
      Samsung Note1072877
      Nexus S153120155
      Flash Galaxy Tab1604563
      Iphone 4309500
      htc desire s4236289
      Iphone 3424680
      Samsung GT-S58301076n/a380

       

       

      And here's the code in question (it's converted from http://shootout.alioth.debian.org/u32/program.php?test=nbody&lang=v8&id=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;

                          }

                }

       

       

      }