C# 加速CSharp编译。发射?

C# 加速CSharp编译。发射?,c#,compilation,roslyn,C#,Compilation,Roslyn,我正在将一个应用程序从.NETFramework移植到.NETCore,它使用运行时代码生成 以下是旧代码: var refs = new [] { typeof(Foo).Assembly.Location, typeof(Enumerable).Assembly.Location }; var options = new CompilerParameters(refs) { GenerateExecutable = false, GenerateInMemor

我正在将一个应用程序从.NETFramework移植到.NETCore,它使用运行时代码生成

以下是旧代码:

var refs = new []
{
    typeof(Foo).Assembly.Location,
    typeof(Enumerable).Assembly.Location
};
var options = new CompilerParameters(refs)
{
    GenerateExecutable = false,
    GenerateInMemory = true
};
var provider = new CSharpCodeProvider();
var result = provider.CompileAssemblyFromSource(options, rawText);
return result.CompiledAssembly;
使用Roslyn的新代码如下所示:

var root = Path.GetDirectoryName(typeof(object).Assembly.Location);
var typeRefs = new[]
{
    typeof(object).Assembly.Location,
    Path.Combine(root, "System.Collections.dll"),
    Path.Combine(root, "System.Runtime.dll"),
    typeof(Foo).Assembly.Location,
    typeof(Enumerable).Assembly.Location
};

var source = Measure("SourceText", () => SourceText.From(rawText));
var parseOptions = CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp7);
var syntaxTree = Measure("Parse", () => SyntaxFactory.ParseSyntaxTree(source, parseOptions));

var compilation = Measure("Compile", () => CSharpCompilation.Create(
    "Bar.dll",
    new[] {syntaxTree},
    typeRefs.Select(x => MetadataReference.CreateFromFile(x)),
    new CSharpCompilationOptions(
        OutputKind.DynamicallyLinkedLibrary,
        optimizationLevel: OptimizationLevel.Debug
    )
));

using var stream = new MemoryStream();

var emitResult = Measure("Emit", () => compilation.Emit(stream));
if(!emitResult.Success)
    throw new Exception("Failed to compile parser code!");

stream.Seek(0, SeekOrigin.Begin);
return Assembly.Load(stream.ToArray());
问题是:新代码的运行速度至少慢了2倍。 我使用了一个非常简单的
Measure
函数来跟踪瓶颈:

private static T Measure<T>(string caption, Func<T> generator)
{
    var now = DateTime.Now;
    var result = generator();
    var end = DateTime.Now - now;
    Debug.WriteLine($"{caption}: {end.TotalMilliseconds} ms");
    return result;
}
如您所见,通过compilation.Emit生成程序集花费了惊人的5.2秒

有没有办法加快速度?可能选项中的某些标志会影响编译时间?我尝试了以下方法,但没有成功:

  • OptimizationLevel.Debug
    OptimizationLevel.Release
  • 将单个源代码拆分为多个源代码部分,每个类一个(这实际上降低了编译速度)
有什么想法吗

SourceText: 4,7926 ms
Parse: 598,5749 ms
Compile: 43,4261 ms
Emit: 5256,0411 ms