16

Roslyn を使用して動的アセンブリにコンパイルするときに、パフォーマンスに問題がありました。コンパイラを使用した場合、同じコードをコンパイルするのに約 300 ミリ秒かかるのに対し、コンパイルには約 3 秒かかりましたCodeDom。コンパイルを行うために使用しているコードの簡素化されたバージョンを次に示します。

var compilation = CSharpCompilation.Create(
                                      "UserPayRules.dll",
                                      syntaxTrees,
                                      assembliesToAdd);

using (var stream = new MemoryStream())
{
    stopWatch.Start();
    var result = compilation.Emit(stream);
    stopWatch.Stop();
    Debug.WriteLine("Compilation: {0}", stopWatch.ElapsedMilliseconds);
    if (!result.Success)
    {
        throw new InvalidOperationException();
    }
    var assembly = Assembly.Load(stream.GetBuffer());
}

この回答は、処理を高速化するために、MemoryStream の代わりに ModuleBuilder オブジェクトを Emit メソッドに渡すことを提案しています。私はそのパターンに従おうとしました。

var compilation = CSharpCompilation.Create(
                                      "UserPayRules.dll",
                                      syntaxTrees,
                                      assembliesToAdd);

var assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(
                                       new AssemblyName("ThisAssembly"),
                                       AssemblyBuilderAccess.RunAndCollect);

var moduleBuilder = assemblyBuilder.DefineDynamicModule("ThisModule");
var result = compilation.Emit(moduleBuilder);

Debug.WriteLine("Compilation: {0}", stopWatch.ElapsedMilliseconds);
if (!result.Success)
{
    throw new InvalidOperationException();
}
var assembly = Assembly.Load(stream.GetBuffer());

しかし、Roslyn の私のバージョンにはEmit、. を受け取るメソッドのオーバーロードがないようModuleBuilderです。そのバージョンは次のとおりです。

Id: Microsoft.CodeAnalysis
バージョン: 0.6.4033103-beta (プレリリース)
プロジェクト情報: http://msdn.microsoft.com/en-US/roslyn

明らかに、これはプレリリースなので、API が変更された可能性があります。でも、

私の質問

  1. Emitメソッドに を受け取るオーバーロードがなくなったように見える理由を知っている人はいModuleBuilderますか?
  2. Roslyn を使用しながら、このコンパイルを高速化する別の方法はありますCodeDomか?
4

1 に答える 1