C# 加速CSharp编译。发射?
我正在将一个应用程序从.NETFramework移植到.NETCore,它使用运行时代码生成 以下是旧代码: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
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