4

我希望将我们代码中某些基于反射的部分替换为使用动态运行时编译性能更好的部分。环顾四周,我发现 Mono 和 Microsoft 都有单独的编译器即服务解决方案:Mono.CSharpMicrosoft.CSharp.

冒着提出基于意见的问题的风险,我想知道这两者如何比较?

据我从非常肤浅的初步调查中可以看出,它们通常都提供 CAAS 功能。我能够使用 Microsoft.CSharp 编译一个“Hello World”类并执行它。虽然我还没有对 Mono 做同样的事情,但我假设它也可以做同样的事情。

有没有人有任何经验或两者都可以评论这个问题?


编辑:我不是在询问 Mono 的 C# 和 Microsoft 的 C# 的比较——我们已经熟悉并使用两者。这个问题专门针对两个CAAS编译器即服务)解决方案。

CAAS不是(无论如何).NET 运行时的标准部分,即还没有System.Compile命名空间。这两个解决方案是 C#Mono.CSharpMicrosoft.CSharp单独的非标准 CAAS 解决方案。他们的界面非常不同,因此是个问题。

Mono 的编译器服务

微软的编译器服务


编辑#2:完全忘记了罗斯林(感谢@Lex Li

4

2 回答 2

4

现在的 Microsoft.CSharp (.net 4.5) 是 C# 编译器用来为 C# 动态表达式发出绑定的 API。因此它是 C# 编译器,但非常有限。.NET 和 Mono 都实现了相同的 API (dll),因此您可以在 .NET 上编译并在 Mono 上运行,反之亦然。

Mono.CSharp 是 Mono C# 编译器的评估器样式 API。它允许您编译任何类似 C# 文本的代码(表达式、语句、类型声明等)并执行它。它严重依赖 System.Reflection 和 System.Reflection.Emit。

这些都与 CodeDom 没有任何关系。

于 2013-10-10T11:50:36.927 回答
0

好吧,我现在进行了比较,结果是 Mono 的版本与之相比表现不佳Mono.CSharpMicrosoft.CSharp

我用两个动态编译器编译了以下代码:

using System;
using CompilerServiceTest;

public class LalaDynamicImpl : ILala
{
    private static int _counter;

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

主程序看起来类似于:

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);
    }
}

在我的机器上,结果是:

  • 静态编译类:1.9s
  • 动态编译类编译Microsoft.CSharp时间:1.9s
  • 动态编译类编译Mono.CSharp时间:10s

结果与 Mono 团队在这里提到的内容以及 Marek Safar 在他的回答中提到的内容一致 -Microsoft.CSharp编译器服务是实际编译器的包装器,并且代码的编译和优化方式与普通代码相同。Mono.Csharp编译器服务与 Mono 编译器是分开的,更像是一个“eval”机器。它不会以与标准编译器相同的方式优化代码。

基本上,Mono 编译器服务似乎并不真正适用于性能关键场景,而是适用于丰富的功能、学习、测试等。

在具有 .NET 4.0 (VS 2010) 和 Mono 3.2.3 的 Windows 7 64 位机器上进行了测试。

于 2013-10-11T11:11:14.813 回答