是否可以使用CodeDOM获取在内存中生成的程序集的流?

时间:2013-11-28 00:44:44

标签: .net-assembly mono.cecil system-codedom-compiler

在我的一些测试中,我需要生成一些程序集,然后使用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()?

1 个答案:

答案 0 :(得分:2)

  

出于性能原因,我想在内存中生成程序集以避免磁盘I / O.

这是编程的伟大神话之一。现代操作系统太聪明,不足以使磁盘I / O成为瓶颈。您的程序实际上并不将程序集写入磁盘,而是将其写入文件系统缓存。内存。写入磁盘的时间稍晚,发生在后台运行的内核线程中,对perf没有影响。

非常相似,将“记忆”视为RAM也是一个神话。程序分配虚拟内存。它根本不是内存,它是在页面文件中分配的空间。在磁盘上。操作系统的工作是在程序需要时为该程序提供该空间。将页面文件分配映射到RAM。写入磁盘的时间稍晚,发生在另一个进程需要RAM时运行的内核线程中。

看到相似度? 没有区别。您可以观察到的唯一可能的副作用是当您在具有非常有限的RAM的计算机上运行时。当文件系统缓存中没有足够的可用空间时,程序必须等待数据写入文件。这样的机器也很难使RAM可用于您的程序。它需要丢弃其他进程(或您自己的)使用的RAM页面,将它们写入磁盘。换句话说,您的程序开始很慢而不是很慢完成工作。净差异接近于零。

程序集从不的大小会对现代计算机上文件系统缓存可用的RAM量造成压力。一个简单的千兆字节至少。所以,不要打扰,你永远不会真正看到性能提升。