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).