在我的一些测试中,我需要生成一些程序集,然后使用ICSharpCode.Decompiler“反编译”它们,它使用Mono.Cecil来检查程序集。
出于性能原因,我想在内存中生成程序集以避免磁盘I / O.
Bellow你可以找到我打算使用的一些代码:
var cdp = CodeDomProvider.CreateProvider(CodeDomProvider.GetLanguageFromExtension("cs"));
var p = new CompilerParameters { GenerateInMemory = true } ;
var cr = cdp.CompileAssemblyFromSource(p, sources);
if (cr.Errors.Count > 0)
{
throw new Exception(cr.Errors[0].ErrorText);
}
// !!! I'd like to avoid building / loading the assembly to / from disk
// var assembly = AssemblyDefinition.ReadAssembly(assemblyPath, readerParameters);
// Instead, I'd like to do something like:
Stream assemblyStream = GetAssemblyContentAsStream(cr.CompiledAssembly);
var assembly = AssemblyDefinition.ReadAssembly(assemblyStream, readerParameters);
var dc = new DecompilerContext(assembly.MainModule);
var astBuilder = new AstBuilder(dc);
astBuilder.AddType(typeToBeConverted);
var output = new StringWriter();
astBuilder.GenerateCode(new PlainTextOutput(output));
所以问题是:是否可以实现GetAssemblyContentAsStream()?
答案 0 :(得分:2)
出于性能原因,我想在内存中生成程序集以避免磁盘I / O.
这是编程的伟大神话之一。现代操作系统太聪明,不足以使磁盘I / O成为瓶颈。您的程序实际上并不将程序集写入磁盘,而是将其写入文件系统缓存。内存。写入磁盘的时间稍晚,发生在后台运行的内核线程中,对perf没有影响。
非常相似,将“记忆”视为RAM也是一个神话。程序分配虚拟内存。它根本不是内存,它是在页面文件中分配的空间。在磁盘上。操作系统的工作是在程序需要时为该程序提供该空间。将页面文件分配映射到RAM。写入磁盘的时间稍晚,发生在另一个进程需要RAM时运行的内核线程中。
看到相似度? 没有区别。您可以观察到的唯一可能的副作用是当您在具有非常有限的RAM的计算机上运行时。当文件系统缓存中没有足够的可用空间时,程序必须等待数据写入文件。这样的机器也很难使RAM可用于您的程序。它需要丢弃其他进程(或您自己的)使用的RAM页面,将它们写入磁盘。换句话说,您的程序开始很慢而不是很慢完成工作。净差异接近于零。
程序集从不的大小会对现代计算机上文件系统缓存可用的RAM量造成压力。一个简单的千兆字节至少。所以,不要打扰,你永远不会真正看到性能提升。