Question

In some of my tests I need to generate some assemblies and then "decompile" them using ICSharpCode.Decompiler which uses Mono.Cecil to inspect assemblies.

For performance reasons I'd like to generate the assembly in memory to avoid disk I/O.

Bellow you can find some code I intend to use:

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));

So the question is: Is it possible to implement GetAssemblyContentAsStream() ?

Was it helpful?

Solution

For performance reasons I'd like to generate the assembly in memory to avoid disk I/O.

This is one of the Great Myths of programming. Modern operating systems are way too smart to make disk I/O a bottleneck. Your program doesn't actually write the assembly to disk, it writes it to the file system cache. RAM. Writing to disk happens later, much later, in a kernel thread that runs in the background and has no effect on perf.

Very similarly, thinking of "memory" as RAM is a myth as well. Programs allocate virtual memory. It is not memory at all, it is space allocated in the paging file. On disk. It is the job of the operating system to make that space available to a program when it needs it. Mapping the paging file allocation to RAM. Writing to the disk happens later, much later, in a kernel thread that runs when another process needs RAM.

See the similarity? There is no difference. The only possible side effect you could ever observe is when you run on a machine that has a very restricted amount of RAM. When there simply isn't enough space available in the file system cache so the program must wait until the data is written to a file. Such a machine will also have great difficulty making the RAM available to your program. It needs to throw out pages of RAM used by other processes (or your own), writing them to disk. In other words, your program will be slow to get started instead of slow to finish the job. The net difference is close to zero.

The size of an assembly never puts a strain on the amount of RAM available to the file system cache on a modern machine. An easy gigabyte at a minimum. So just don't bother, you'll never actually see a performance improvement.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top