My past experiences with Mono left me unimpressed because of it's speed issues, in some cases the .NET Framework runing six times faster. But because a lot of people claim that Mono gets faster with every build, today I decided to run a small series of tests to see if there have been any improvements. The results have been very surprising as you will see below.
First of all, this is the C# code used for my tests. Sorry if it's a little messy :-)
using System;
using System.Collections;
namespace TestNamespace
{
public class TestClass
{
static long ticks = 0;
public static void InitTicks()
{
TestClass.ticks = DateTime.Now.Ticks;
}
public static void ShowTime(string str)
{
long newTicks = DateTime.Now.Ticks;
//milliseconds, not Microsoft :)
double ms = (newTicks - TestClass.ticks) / TimeSpan.TicksPerMillisecond;
Console.WriteLine("{0}{1} ms", str.PadRight(35, '.'), ms);
TestClass.ticks = DateTime.Now.Ticks;
}
public static void Test1()
{
ArrayList a = new ArrayList();
for(int i=0;i<1000000;i++)
{
string str = i.ToString();
a.Add(str);
}
ShowTime("ArrayList strings test");
System.Text.StringBuilder strBuilder = new System.Text.StringBuilder();
Random rnd = new Random();
foreach(object strObj in a)
{
strBuilder.Append(strObj as string);
strBuilder.Append(rnd.Next().ToString());
}
string s = strBuilder.ToString();
if(s == "Dsadasdasdsa")
{
throw(new Exception("no way..."));
}
ShowTime("StringBuilder test");
}
public static void Test2()
{
int i = 0;
double d = 0.0;
for(i=0; i<1000000000; i++)
{
d += i;
}
double d2 = d/2;
ShowTime("Integer & Floating ADD");
}
public static void Test3()
{
int i = 0;
int sum = 0;
for(i=0;i<100000;i++)
{
try
{
if(i is int)
{
throw(new Exception("the i integer is an integer.. oh no..."));
}
}
catch(Exception ex)
{
if(ex is NotImplementedException)
{
Console.Write("who's responsable for this ?");
}
}
}
int res = sum/2;
if(res == -321)
throw(new Exception("this is odd"));
ShowTime("Exception test");
}
public static void Recursive(string str)
{
string name = System.Reflection.MethodBase.GetCurrentMethod().Name;
if(str.Substring(0, name.Length) == name)
{
int i = Convert.ToInt32(str.Substring(name.Length));
if(i < 1000)
{
// Console.Write(i.ToString()+"\n");
Recursive(name + (i+1).ToString());
}
}
}
public static void Test4()
{
for(int i=0;i<1000;i++)
{
Recursive("Recursive0");
}
ShowTime("Reflection and recursion");
}
public static void Main()
{
InitTicks();
Test1();
Test2();
Test3();
Test4();
}
}
}
This code contains 5 tests:
Test name
Function name
Details
ArrayList test
Test1, 1st part
1 million strings are inserted into an ArrayList.
StringBuilder test
Test1, 2nd part
The strings from the ArrayList are appended to a StringBuilder.
Integer & Floating ADD test
Test2
An integer is added to a double 1 billion times.
Exception test
Test3
100.000 exceptions are thrown.
Recursion and reflection test
Test4
A recursive function that calls GetCurrentMethod() is called for 1000 times. (see more details in code)
I almost forgot to specify my configuration: Athlon XP 2600+, 1 GB RAM PC2700, 80 GB 7200 2MB HDD, WindowsXP SP2. Now, to the really interesting part.
There are the results when compiling with the optimizations off. As you can see, it's unbelievable how similar the timings are.
-----------------------------------------------------------------------------
Running Mono binary:
ArrayList strings test.............890 ms
StringBuilder test.................1046 ms
Integer & Floating ADD.............2000 ms
Exception test.....................890 ms
Reflection and recursion...........3859 ms
-----------------------------------------------------------------------------
Running Framework binary:
ArrayList strings test.............921 ms
StringBuilder test.................1062 ms
Integer & Floating ADD.............1968 ms
Exception test.....................859 ms
Reflection and recursion...........3859 ms
-----------------------------------------------------------------------------
When I turned the optimizations on in both CSC and MCS (the Mono C# compiler) the Integer & Floating ADD Test ran two times faster with the .NET Framework. However, because this is a very simple test, the optimizations used may not be appliable in any real-life applications. Other than that there are no noticeable differences between the timings obtained with or without the optimize+ flag. That's right, the same flags are used in Mono, but they are passed with a '-' charater instread of a '/'. Here are he results:
-----------------------------------------------------------------------------
Running Mono binary:
ArrayList strings test.............890 ms
StringBuilder test.................1046 ms
Integer & Floating ADD.............2015 ms
Exception test.....................859 ms
Reflection and recursion...........3890 ms
-----------------------------------------------------------------------------
Running Framework binary:
ArrayList strings test.............921 ms
StringBuilder test.................1078 ms
Integer & Floating ADD.............984 ms
Exception test.....................812 ms
Reflection and recursion...........3875 ms
-----------------------------------------------------------------------------
With speed no longer an issue, the only important thing that is now missing from Mono is Windows.Forms, but this is under heavy development and I'm sure we are going to see it in future releases.
After doing these tests and viewing the results, I only have two gthings to say:
1. Thank you Microsoft for .NET and C#.
2. Thank you Mono for true cross-platform development (almost there).
