0

私のテストのいくつかでは、いくつかのアセンブリを生成し、 Mono.Cecil を使用してアセンブリを検査するICSharpCode.Decompilerを使用してそれらを「逆コンパイル」する必要があります。

パフォーマンス上の理由から、メモリ内にアセンブリを生成してディスク I/O を回避したいと考えています。

以下に、使用する予定のコードをいくつか示します。

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() を実装することは可能ですか?

4

1 に答える 1

2

パフォーマンス上の理由から、メモリ内にアセンブリを生成してディスク I/O を回避したいと考えています。

これは、プログラミングの偉大な神話の 1 つです。最新のオペレーティング システムは、ディスク I/O をボトルネックにするほど賢くありません。プログラムは実際にアセンブリをディスクに書き込むのではなく、ファイル システム キャッシュに書き込みます。羊。ディスクへの書き込みは、かなり後で、バックグラウンドで実行され、パフォーマンスに影響を与えないカーネル スレッドで行われます。

同様に、「メモリ」を RAM と考えるのも神話です。プログラムは仮想メモリを割り当てます。これはメモリではなく、ページング ファイルに割り当てられた領域です。ディスク上。必要なときにプログラムがそのスペースを使用できるようにするのは、オペレーティング システムの仕事です。ページング ファイルの割り当てを RAM にマッピングします。ディスクへの書き込みは、かなり後で、別のプロセスが RAM を必要とするときに実行されるカーネル スレッドで行われます。

類似点がわかりますか? 違いはありません。唯一の可能性のある副作用は、RAM の量が非常に制限されたマシンで実行した場合です。ファイル システム キャッシュに十分な空き容量がない場合、プログラムはデータがファイルに書き込まれるまで待機する必要があります。このようなマシンでは、RAM をプログラムで使用できるようにすることも非常に困難になります。他のプロセス (または独自のプロセス) で使用されている RAM のページを破棄して、それらをディスクに書き込む必要があります。言い換えれば、プログラムは仕事を終えるのが遅くなるのではなく、開始するのが遅くなります。正味の差はほぼゼロです。

アセンブリのサイズが、最新のマシンのファイル システム キャッシュに使用できる RAM の量に負担をかけることはありません。最小で簡単なギガバイト。気にしないでください。実際にパフォーマンスが向上することはありません。

于 2013-11-28T14:28:12.233 に答える