Skip navigation
zet23t
Currently Being Moderated

Runtime performance Android vs. Iphonea

Apr 26, 2012 12:00 PM

Tags: #air #iphone #android #ios #performance #benchmark

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&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;

                    }

          }

 

 

}

 
Replies
  • Chris Campbell
    8,774 posts
    May 4, 2010
    Currently Being Moderated
    Apr 26, 2012 3:26 PM   in reply to zet23t

    Thank you for the detailed post.  I'm forwarding this to the iOS team for their review.

     

    Chris

     
    |
    Mark as:

More Like This

  • Retrieving data ...

Bookmarked By (0)

Answers + Points = Status

  • 10 points awarded for Correct Answers
  • 5 points awarded for Helpful Answers
  • 10,000+ points
  • 1,001-10,000 points
  • 501-1,000 points
  • 5-500 points