Browse Source

Add performance benchmark

hughsando 10 years ago
parent
commit
cb6ef15ea8

+ 141 - 0
tests/benchs/mandelbrot/Mandelbrot.hx

@@ -0,0 +1,141 @@
+#if (!js && !flash)
+import haxe.io.Bytes;
+#end
+
+#if anon_objects
+typedef RGB = { r:Int, g:Int, b:Int };
+typedef Complex = { i:Float, j:Float };
+#else
+class RGB
+{
+   public var r:Int;
+   public var g:Int;
+   public var b:Int;
+
+   public function new(inR:Int, inG:Int, inB:Int)
+   {
+      r = inR;
+      g = inG;
+      b = inB;
+   }
+}
+
+class Complex
+{
+   public var i:Float;
+   public var j:Float;
+   
+   public function new(inI:Float, inJ:Float)
+   {
+      i = inI;
+      j = inJ;
+   }
+}
+#end
+
+
+
+class Mandelbrot
+{
+   static inline var SIZE = 10;
+   static inline var MaxIterations = 1000;
+   static inline var MaxRad = 1<<16;
+   static inline var width = 35*SIZE;
+   static inline var height = 20*SIZE;
+
+
+   public static function main()
+   {
+      var t0 = now();
+
+      var palette = [];
+      for(i in 0...MaxIterations+1)
+         palette.push( createPalette(i/MaxIterations) );
+
+      var image = [];
+      image[ width*height-1 ] = null;
+      var outPixel = 0;
+      var scale = 0.1/SIZE;
+      for(y in 0...height)
+      { 
+         if ( (y%10)== 0)
+            trace(y);
+         for(x in 0...width)
+         {
+            var offset = createComplex(x*scale - 2.5,y*scale - 1);
+            var val = createComplex(0.0,0.0);
+            var iteration = 0;
+            while( complexLength2(val)<MaxRad && iteration<MaxIterations)
+            {
+               val = complexAdd( complexSquare(val), offset );
+               iteration++;
+            }
+            image[outPixel++] = palette[iteration];
+         }
+      }
+
+      var time = now()-t0;
+      trace('Mandelbrot $width x $height : $time s');
+
+      #if (!js && !flash)
+      var header = 'P6 $width $height 255\n';
+      var buffer = Bytes.alloc(header.length + width*height*3);
+      var pos = header.length;
+      buffer.blit(0,  Bytes.ofString(header), 0, pos );
+      for(pixel in image)
+      {
+         buffer.set(pos++, pixel.r);
+         buffer.set(pos++, pixel.g);
+         buffer.set(pos++, pixel.b);
+      }
+      sys.io.File.saveBytes("mandelbrot.ppm", buffer);
+      #end
+
+   }
+
+   public static function now()
+   {
+      #if cppia
+      return 0;
+      #else
+      return haxe.Timer.stamp();
+      #end
+   }
+
+   public static function complexLength2(val:Complex) : Float
+   {
+      return val.i*val.i + val.j*val.j;
+   }
+
+   public static function complexAdd(val0:Complex, val1:Complex)
+   {
+      return createComplex( val0.i + val1.i, val0.j + val1.j );
+   }
+
+   public static function complexSquare(val:Complex)
+   {
+      return createComplex(  val.i*val.i - val.j*val.j, 2.0 * val.i * val.j );
+   }
+
+
+   #if anon_objects
+   inline public static function createComplex(inI:Float, inJ:Float) return { i:inI, j:inJ };
+   #else
+   inline public static function createComplex(inI:Float, inJ:Float) return new Complex(inI, inJ);
+   #end
+
+
+   public static function createPalette(inFraction:Float)
+   {
+      var r = Std.int(inFraction*255);
+      var g = Std.int((1-inFraction)*255);
+      var b = Std.int( (0.5-Math.abs(inFraction-0.5))*2*255 );
+      #if anon_objects
+      return { r:r, g:g, b:b };
+      #else
+      return new RGB(r,g,b);
+      #end
+   }
+}
+
+

+ 32 - 0
tests/benchs/mandelbrot/Readme.md

@@ -0,0 +1,32 @@
+This test has not been written for pure speed - object allocations are deliberately (over) used to measure how memory access/GC mixes with numeric processing.
+
+Each target generates 2 outputs - one that uses classes and one that uses anonymous objects, so the speed can be compared.
+
+Usage:
+```
+haxe compile-cpp.hxml
+./bin/cpp/Mandelbrot
+./bin/cpp-anon/Mandelbrot
+
+# Note - need to time externally at the moment
+haxe compile-cppia.hxml
+time haxelib run hxcpp bin/Mandelbrot.cppia
+time haxelib run hxcpp bin/Mandelbrot-anon.cppia
+
+# Time externally to get sub-second accuracy
+haxe compile-java.hxml
+time java -jar bin/java/Mandelbrot.jar
+time java -jar bin/java-anon/Mandelbrot.jar
+
+haxe compile-js.hxml
+node bin/Mandelbrot.js
+node bin/Mandelbrot-anon.js
+
+haxe compile-neko.hxml
+neko bin/Mandelbrot.n
+neko bin/Mandelbrot-anon.n
+
+haxe compile-php.hxml
+php bin/php/index.php
+php bin/php-anon/index.php
+```

+ 7 - 0
tests/benchs/mandelbrot/compile-cpp.hxml

@@ -0,0 +1,7 @@
+-main Mandelbrot
+-cpp bin/cpp
+
+--next
+-main Mandelbrot
+-cpp bin/cpp-anon
+-D anon_objects

+ 9 - 0
tests/benchs/mandelbrot/compile-cppia.hxml

@@ -0,0 +1,9 @@
+-main Mandelbrot
+-cpp bin/Mandelbrot.cppia
+-D cppia
+
+--next
+-main Mandelbrot
+-cpp bin/Mandelbrot-anon.cppia
+-D cppia
+-D anon_objects

+ 7 - 0
tests/benchs/mandelbrot/compile-java.hxml

@@ -0,0 +1,7 @@
+-main Mandelbrot
+-java bin/java
+
+--next
+-main Mandelbrot
+-java bin/java-anon
+-D anon_objects

+ 7 - 0
tests/benchs/mandelbrot/compile-js.hxml

@@ -0,0 +1,7 @@
+-main Mandelbrot
+-js bin/Mandelbrot.js
+
+--next
+-main Mandelbrot
+-js bin/Mandelbrot-anon.js
+-D anon_objects

+ 7 - 0
tests/benchs/mandelbrot/compile-neko.hxml

@@ -0,0 +1,7 @@
+-main Mandelbrot
+-neko bin/Mandelbrot.n
+
+--next
+-main Mandelbrot
+-neko bin/Mandelbrot-anon.n
+-D anon_objects

+ 7 - 0
tests/benchs/mandelbrot/compile-php.hxml

@@ -0,0 +1,7 @@
+-main Mandelbrot
+-php bin/php
+
+--next
+-main Mandelbrot
+-php bin/php-anon
+-D anon_objects

+ 0 - 0
tests/benchs/MTNetwork.hx → tests/benchs/mtnetwork/MTNetwork.hx