リリースモードでコンパイルすると、デバッグモードよりも最適化されたコードが生成されると聞きました。これは問題ありません。
しかし、この最適化はILで行われるのでしょうか。CLRが実行すると、マシンコードに含まれますか?メタデータ構造は、リリースおよびデバッグでコンパイルされたPEとは異なりますか?
ありがとう
リリースモードでコンパイルすると、デバッグモードよりも最適化されたコードが生成されると聞きました。これは問題ありません。
しかし、この最適化はILで行われるのでしょうか。CLRが実行すると、マシンコードに含まれますか?メタデータ構造は、リリースおよびデバッグでコンパイルされたPEとは異なりますか?
ありがとう
リリースビルドでビルドすると、C#コンパイラの/optimizeコンパイルオプションがオンになります。これにはいくつかの副作用があります。ILは実際に変化しますが、それほど大きくはありません。注目すべきは、コンパイラがコードを完全にデバッグ可能にするための努力をしなくなったことです。たとえば、空の静的コンストラクターをスキップし、中括弧にブレークポイントを設定できるNOPオペコードを発行しなくなり、異なるスコープのローカル変数をスタックフレームでオーバーラップできるようになります。小さなもの。
最も重要な違いは、アセンブリに対して発行される[Debuggable]属性であり、そのIsJITOptimizerDisabledプロパティはfalseです。
これにより、ジッターに組み込まれている実際のオプティマイザーがオンになります。この回答には、実行される最適化のリストがあります。このアプローチの有用性に注意してください。どの言語でも、コンパイラの代わりにコードオプティマイザをジッターに含めることでメリットが得られます。
つまり、一言で言えば、ILの非常に小さな変更、生成されたマシンコードの非常に大きな変更です。
はい、ILにはいくつかの最適化があります。特に、デバッグバージョンには、デバッガーがブレークポイントを簡単に挿入できるようにするNOP命令が含まれていると思います。提供されるデバッグ情報のレベル(行番号など)に関しても、潜在的に違いがあります。
小さなサンプルプログラムを取り、それを両方の方法でコンパイルしてから、の出力を確認することをお勧めしますildasm
。
C#コンパイラはあまり最適化を行いません-JITコンパイラはそのほとんどを行います-しかし、いくつかの違いがあると思います。
シルは異なり、最適化されています。機械語はcilの翻訳であるため、それも異なります。Visual Studioで分解ウィンドウを開くだけで、自分で確認できます。リリース間でクラスコントラクトの構造を変更しないため、メタデータは同じままである必要があります。
VBでは、実行可能ファイルにコンパイルされたEdit + Continueサポートの副作用があり、メモリリークが発生する可能性があります。WithEventsキーワードで宣言されたイベントの影響を受けます。WeakReferenceは、これらのイベントインスタンスを追跡します。問題は、デバッガーなしでアプリを実行すると、これらのWeakReferencesがリークされることです。プロセスがメモリを消費する速度は、クラスのインスタンスがいくつ作成されるかに大きく依存します。リークは、オブジェクトごとのイベントごとに16バイトです。
免責事項:ここでハンスの答えからコピー
このマイクロソフトサポート技術情報の記事を参照してください。
これは正確な質問に対する答えではありません。さらに、プリプロセッサマークアップを使用して、デバッグモードで実行する必要のあるコードとリリースモードで実行する必要のあるコードを意図的にマークすることができます。
#if DEBUG
// code only meant for debug mode
#endif
#if NOT DEBUG
// code only meant for release mode
#endif
したがって、これを行うと、異なるILが生成されます。