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 が変更された可能性があります。でも、
私の質問
Emit
メソッドに を受け取るオーバーロードがなくなったように見える理由を知っている人はいModuleBuilder
ますか?- Roslyn を使用しながら、このコンパイルを高速化する別の方法はあります
CodeDom
か?