简体   繁体   English

如何缓存程序集以供以后编译? [罗斯林]

[英]How to cache assemblies for later compile? [Roslyn]

In my project I'm gonna compile lots of assemblies using the same reference assemblies for each compilation (about 30 dlls).在我的项目中,我将为每次编译(大约 30 个 dll)使用相同的参考程序集编译大量程序集。 Seems like after the first compilation reference assemblies are cached and huge speed boost is achieved starting from second compilation (1360ms -> 40ms).似乎在第一次编译参考程序集被缓存后,从第二次编译(1360ms -> 40ms)开始实现了巨大的速度提升。 I want to cache all reference assemblies before compiling new assemblies.我想在编译新程序集之前缓存所有引用程序集。

Assemblies are cached during CSharpCompilation.Create(name, syntaxTrees, references) method.程序集在CSharpCompilation.Create(name, syntaxTrees, references)方法期间被缓存。 This method requires syntaxTree to compile, but I only want to cache references.这个方法需要syntaxTree编译,但我只想缓存引用。 What I need to invoke to cache references?我需要调用什么来缓存引用?

Main compilation code:主要编译代码:

List<MetadataReference> references = new List<MetadataReference>();
foreach (var reference in assemblies)
{
   try
   {
      references.Add(MetadataReference.CreateFromFile(reference));
   }
   catch (Exception e)
   {
      error += e + "\n";
      exitCode |= (int)ExitCode.ReferenceError;
   }
}

CSharpCompilation compilation = null;
compilation = CSharpCompilation.Create(
   assemblyName,
   syntaxTrees: syntaxTree,
   references: references,
   options: new CSharpCompilationOptions(
      OutputKind.DynamicallyLinkedLibrary,
      optimizationLevel: OptimizationLevel.Release,
      allowUnsafe: true));

Note that the cost of the 'first run' might not be the consumed assemblies, but simply the runtime having to JIT Roslyn itself;请注意,“首次运行”的成本可能不是消耗的程序集,而只是运行时必须 JIT Roslyn 本身; later Compilations are taking advantage of that fact as well.后来的编译也利用了这一事实。

That said, there are already caches behind the scenes where we reuse the loaded metadata information between created Compilations.也就是说,我们在创建的编译之间重用加载的元数据信息的幕后已经有缓存。 Those will kick in automatically as long as we recognize the assemblies are being reused.只要我们认识到这些程序集正在被重用,它们就会自动启动。 The best way to ensure the cache is being used would be to reuse the same MetadataReference objects you get back from CreateFromFile just to simplify the cache being triggered.确保使用缓存的最佳方法是重用您从 CreateFromFile 返回的相同 MetadataReference 对象,以简化被触发的缓存。 But you don't really have to do any explicit caching -- we're already doing that for you!但是您实际上并不需要进行任何显式缓存——我们已经为您做到了!

Note you can also create a Compilation from an existing Compilation but replacing syntax trees;请注意,您还可以从现有编译创建编译,但替换语法树; so you could make a single Compilation with just the references, and then take that and call.WithSyntaxTree() to produce a new Compilation with those trees -- you can keep going back to that first one and 'forking' it with new trees.因此您可以仅使用引用进行单个编译,然后将其调用并调用.WithSyntaxTree() 以使用这些树生成新的编译——您可以继续返回第一个编译并用新树“分叉”它。 That might be a bit faster as well, but you'd have to benchmark it accordingly.也可能会更快一些,但您必须相应地对其进行基准测试。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM