Mono

Recently, the Mono project has released the 1.0 version of its framework. I followed the development closely, because the concept of running .net application on unices is very interesting. You can say what you will about MS and its business policy, but .net framework is really elegant solution, and C# is a nice and clean language (IMO, much cleaner than Java), and it shows it's been designed by a Pascal/Delphi lover :).

As soon as I got the chance, I installed mono on my desktop machine, both on FreeBSD and WinXP (in dual-boot), and started playing with it. The impressions are very good for starts, and it seems to deliver what's promised. The only disappointment is that Windows.Forms support is practically unusable (so no cross-platform GUI applications yet, except for Gtk#), but it should be addressed in Mono 1.2. Except for that, as far as I can tell, the stuff really works.

Mono can be run on FreeBSD (ports/lang/mono) only on a recent -CURRENT system (mine is from 2004-07-10; it won't work on 5.2[.1]-RELEASE), and even now, there are some threading problems: one is detected by the ./configure script (abnormality with a certain garbage collector), and one I stumbled on myself: monodoc cannot be compiled (it seems that the C# compiler blows up on a bug in libpthread). Gtk# (ports/x11-toolkits/gtk-sharp) installs cleanly and most of the demos work (there is an occasional Null pointer reference, but this seems to be because of demo programming error, rather than interpreter fault).

As is the custom, I started writing some hello world programs, and, since I like my solutions to be of maximum available performance, done a simple speed benchmark. The benchmark consists of this C# code (it intentionally mixes floating-point and integer code):

using System;

class Bench {
    public static void Main() {
        double d = 0;
        for (int i = 0; i < 1000000000; i++) {
            d = d + i;
        }
        Console.WriteLine(d);
    }
}

I've run this script on Win32 using MS .NET and Mono runtimes, and on FreeBSD with Mono runtime. Also, I've written equivalent C and Java programs, for comparison. Here are the results (less is better):

PlatformTime/sec.
Win32 MS .NET2.8
Win32 Mono15.1
Win32 gcc -O33.2
Win32 java -client9.4
Win32 java -server11.7
FreeBSD Mono7.9
FreeBSD gcc -O32.7
FreeBSD java -client9.7
FreeBSD java -server11.7

Benchmark code & environment (for win32) can be downloaded here.

This is only a simple first-hand comparison, just to get a feel for the performance of various platforms. Gcc on FreeBSD was 3.3, while on Win32 it's 3.2 (MinGW), so this might account for the variation in performace. Other than that, it's surprising to see interpreted (well, JIT compiled) .net code outperform gcc-compiled C code on win32! Although Mono uses JIT (at least reports it does when used with --stats), it's about 5 times slower than the one in MS .net. I used the same executable with Win32 MS .NET, Win32 Mono, and FreeBSD Mono cases, and I don't know how it managed so much better performance on FreeBSD (performance on Linux should be similar, it's probably because of native unix environment). The JIT is used in all .net cases presented above: I tried timing equivalent programs written for purely interpreted platforms: Python, Ruby and Perl (yes, all three...), and they took about half an hour on average to execute.

Startup time was included for all cases (a few test runs of each were made to preload the libraries into the OS cache), so this could be the reason why java (especially with -server) performs so poorly (1.4.2 VM). But then again, .net has similar sized libraries...

This, of couse, is an overly simplistic look on the platforms involved. A more seriuis benchmark would have to involve at least string operations, and I'll do it if find the time. Until then, I can only say I like what I see here!