Question

I am looking to replace certain reflection-based parts of our code with ones that perform better using dynamic runtime compilation. Looking around I saw that both Mono and Microsoft have separate Compiler-as-a-Service solutions: Mono.CSharp and Microsoft.CSharp.

With the risk of asking an opinion-based question, I'm wondering how these two compare?

As far as I can tell from a very superficial initial investigation, they both generally provide CAAS capabilities. I was able to compile a "Hello World" class using Microsoft.CSharp and execute it. And although I didn't do the same thing with the Mono one yet, I'm assuming it could do the same.

Does anyone have any experience with either or both and can comment on the issue?


Edit: I am not asking about a comparison of Mono's C# and Microsoft's C# - we are already familiar with and using both. The question is specifically about the two CAAS (Compiler-as-a-Service) solutions.

CAAS isn't (yet anyway) a standard part of the .NET runtime, i.e there is no System.Compile namespace yet. The two solutions Mono.CSharp and Microsoft.CSharp are separate non-standard CAAS solutions for C#. Their interfaces are very different and hence the question.

Mono's compiler service

Microsoft's compiler service


Edit #2: Completely forgot about Roslyn (thanks to @Lex Li)

Was it helpful?

Solution

Microsoft.CSharp as it's now (.net 4.5) is API used by C# compiler to emit bindings for C# dynamic expressions. Therefore it's C# compiler but very limited. The same API (dll) is implemented by both .NET and Mono so you can compile on .NET and run on Mono and vice-versa.

Mono.CSharp is evaluator style API to Mono C# compiler. It allows you to compile any C# text-like code (expressions, statement, type declarations, etc) and execute it. It relies on System.Reflection and System.Reflection.Emit heavily.

Neither of these have any relation to CodeDom.

OTHER TIPS

Well I have now compared Mono.CSharp with Microsoft.CSharp and the result is that Mono's version performs badly in comparison.

I compiled the following code with both dynamic compilers:

using System;
using CompilerServiceTest;

public class LalaDynamicImpl : ILala
{
    private static int _counter;

    public void DoLala()
    {
        _counter++;
    }
}

The main program looks something along the lines of:

public interface ILala
{
    void DoLala();
}

public class LalaStaticImpl : ILala
{
    private static int _counter;

    public void DoLala()
    {
        _counter++;
    }
}

public class Program
{
    public static void Main(string[] args)
    {
        Message("Compiling dynamic lala...");
        var lala = BuildDynamicLala();

        Message("Testing dynamic lala...");
        Test(lala);

        Message("Sleeping for 1s...");
        GC.Collect();
        Thread.Sleep(1000);

        Message("Testing static lala...");
        Test(new LalaStaticImpl());
    }

    private static void Test(ILala lala)
    {
        var watch = Stopwatch.StartNew();
        for (var i = 0; i < 1000000000; i++)
            lala.DoLala();
        Console.WriteLine(watch.Elapsed);
    }
}

On my machine the results are:

  • Statically compiled class: 1.9s
  • Dynamically compiled class compiled with Microsoft.CSharp: 1.9s
  • Dynamically compiled class compiled with Mono.CSharp: 10s

The results correspond with what the Mono team mentions here and what Marek Safar mentions in his answser - the Microsoft.CSharp compiler service is a wrapper for the actual compiler and the code is compiled and optimized in the same way as normal code. The Mono.Csharp compiler service is separate from the Mono compiler and is more of an "eval" machine. It does not optimize the code in the same way as the standard compiler.

Basically it appears that the Mono compiler service isn't really intended for performance-critical scenarios, but for rich features, learning, testing, etc.

Tested on a Windows 7 64bit machine with .NET 4.0 (VS 2010) and Mono 3.2.3.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top