I’m always interested in performance comparisons. In the RIA world, two that you may have seen are Bubblemark and more recently GUIMark. Those tests look at graphics; I thought it would be fun to look at some tight code in a loop.
You can try the test here.
The code is below. If I’ve done something that tilts the test in favour of one or the other runtime, let me know.
Please don’t take this too seriously. I may have messed up the test; it is only one small aspect of performance; and there are lots of other factors to think about. I just find this sort of thing interesting.
ActionScript code:
public function countprimes():void { var n:int = int(testnum.text); var start: Date = new Date; var i: int; var j: int; var numprimes: int; var limit: Number; numprimes = 1; // 2 is prime for (i = 3; i<= n; i+=2) { var isPrime: Boolean = true; limit = Math.ceil(Math.sqrt(i)) + 1; for (j = 3; j < limit; j+=2) { if (i % j == 0) { isPrime = false; break; } if (isPrime != true) { continue; } } if (isPrime) { numprimes ++; } } var end: Date = new Date; var timetaken:Number = Number(int(end) - int(start)); timetaken = timetaken / 1000; lbresult.text = "Number of primes up to: " + n + " is " + numprimes + ", counted in " + timetaken + " secs."; }
C# Code:
void btnCount_Click(object sender, RoutedEventArgs e) { int n = Int32.Parse(this.txtMaxNum.Text); DateTime start = DateTime.Now; int i; int j; int numprimes; double limit; numprimes = 1; //2 is prime for (i = 3; i<= n; i+=2) { bool isPrime = true; limit = Math.Ceiling(Math.Sqrt(i)) + 1; for (j = 3; j < limit; j+=2) { if (i % j == 0) { isPrime = false; break; } if (isPrime != true) { continue; } } if (isPrime) { numprimes ++; } } DateTime end = DateTime.Now; Double timetaken = end.Ticks - start.Ticks; timetaken = timetaken / 10000000; this.lbMessage.Text = "Number of primes up to: " + n + " is " + numprimes + ", counted in " + timetaken + " secs."; }
No really surprising. Silverlight is compiled C# and ActionScript is script.
@Craig
No, ActionScript is JIT-compiled too, in the latest versions.
Tim
I thought the most interesting thing was that the Silverlight one appeared more quickly.
Cool experiment.
I translated your ActionScript code to JavaScript, and put this up here:
http://www.tobinharris.com/primes.html
In Safari on my iMac 2.4Ghz that took 5.75 seconds to run. In Firefox it took 7.077 seconds. Both examples used 1,000,000 as the value.
So, quite a huge difference to the 1.22 seconds in Flash, and 0.414 seconds in SilverLight (hosted in Safari).
On my Opteron 175 pc the Flash version clocks out to 2.297 sec., the Silverlight to 0.90625 sec. and my Java version to 0.767
Unfortunately I don’t see anything below “Silverlight” – flash works fine.
this is true as well in the latest stable firefox (2.0.0.16) as in internet explorer 7.0, in windows xp prof. and vista prof.
Pretty cool.
On my computer Flash took an average of 2.4 seconds and Silverlight took an average of 0.9 seconds.
But the first think I noticed, echoing Duncan Smart’s observation, was that the Silverlight applet loaded much quicker than did the Flash one.
Did you use AS2 or AS3 for the Flash test?
My understanding is that AS3 is supposed to run much more efficiently than AS2, in which case it is an important consideration when comparing Flash to Silverlight.
To Bob F: I have implemented the code targeting Flash 9 and it seems this test is indeed Flash 9 vs Silverlight 2.
rewriting the script for flash that change all int to Number, it enhance the performance from 3.953 to 3.532sec on my machine.
public function countprimes():void {
var n:Number = parseInt(testnum.text);
var start: Date = new Date;
var i: Number;
var j: Number;
var numprimes: Number;
var limit: Number;
numprimes = 1; // 2 is prime
for (i = 3; i<= n; i+=2)
{
var isPrime: Boolean = true;
limit = Math.ceil(Math.sqrt(i)) + 1;
for (j = 3; j < limit; j+=2)
{
if (i % j == 0)
{
isPrime = false;
break;
}
if (isPrime != true)
{
continue;
}
}
if (isPrime)
{
numprimes ++;
}
}
var end: Date = new Date;
var timetaken:Number = Number(int(end) – int(start));
timetaken = timetaken / 1000;
lbresult.text = “Number of primes up to: ” + n + ” is ” + numprimes + “, counted in ” + timetaken + ” secs.”;
}
@injie
Interesting thanks.
Tim
fyi, on the ActionScript example, moving the isPrime declaration out of the loop like so:
—
var isPrime: Boolean;
for (i = 3; i<= n; i+=2)
{
isPrime = true;
—
should give a performance boost as the variable space doesnt have to be reallocated each loop.
On my machine, I am getting about a 20% performance.
I am not sure how the same change would affect the C# code.
mike chambers
mesh@adobe.com
Mike
Thanks for the comment. Strangely your modified code runs slightly slower on my system. Odd as I see your logic. Are you on Mac or Windows?
Tim
Google Chrome JavaScript (V8)
Number of primes up to: 1000000 is 78498, counted in 3.216 secs.
I took the code and wrote a detailed article on improving it with multithreading inside Silverlight.
http://www.silverlighthack.com/post/2008/09/07/Silverlight-MultiThreading-with-a-Computational-Process
I don’t think that Flash/Flex have true multithreading…so this makes Silverlight even faster! On my machine I got about a 100% improvement in speed.
I am actually looking for engineers interested in working on a new UI Platform product similar to Silverlight. Anyone interested?
-Ryan Phillips
engineerfinder@live.com
Tweaking the code slightly to optimize unnecessary floating-point and calculations, I get (on my crappy little laptop):
C/x86 ~1s
C#/CLR ~1s
JS/V8 ~1.5s
AS3/AVM2 ~3s
This benchmark on an x86 will generally end up with an inner loop of:
idiv eax,ecx
test edx,edx
I havent looked up the cycle counts, but I wouldn’t expect modern CPU to heavily optimize integer division – as its pretty much a rare edge case.
Code (C#/C flavor):
int primes(int n)
{
int numprimes=1;
int l=2;
int l2=l*l;
int i;
int j;
for (i=3; il2)
{
l++;
l2=l*l;
}
numprimes++;
for (j = 3; j < l+1; j+=2)
{
if (i % j == 0)
{
numprimes–;
break;
}
}
}
return numprimes;
}
whoops code got truncated, the loop should read:
for (i=3; il2)
{
l++;
l2=l*l;
}
numprimes++;
for (j = 3; j < l+1; j+=2)
{
if (i / j == 0)
{
numprimes--;
break;
}
}
}
for (i=3; i l2)
{
l++;
l2=l*l;
}
numprimes++;
for (j = 3; j < l+1; j+=2)
{
if (i / j == 0)
{
numprimes--;
break;
}
}
}
Have you try it in JavaFX? Here is the Link:
http://javafx.com/samples/PrimeFactors/index.html
Try it! It really fast! Fastest than AdobeFlash, Microsoft Silverlight and JavaScript.
the javafx sample isn’t very impressive since it won’t even come up….seems like it takes forever to load any of those javafx examples….not even in the same class as flex and silverlight.
Update: with silverlight3 its even more impressive. Within Firefox 3 we have:
Flash10: Number of primes up to: 1000000 is 78498, counted in 1.247 secs.
Silverlight3: Number of primes up to: 1000000 is 78498, counted in 0.22 secs.
Adobe should take care for the performance of its JIT.
I concur that the Javafx sample is unimpressive.
I intend to use the multithreading optimisation to give this a go myself.
Silverlight came out twice as fast using the example page.
Manufacturer Gigabyte Technology Co., Ltd.
Model GA-MA785GT-UD3H
Total amount of system memory 8.00 GB RAM
System type 64-bit operating system
Number of processor cores 4