web-dev-qa-db-ja.com

デバッグとリリースのパフォーマンス

私は次の段落に遭遇しました:

「IDEのVisual Studioでコードをコンパイルするときのデバッグとリリースの設定は、パフォーマンスにほとんど違いはありません...生成されたコードはほとんど同じです。C#コンパイラは実際には何もしません。最適化C#コンパイラはILを吐き出すだけで、実行時にすべての最適化を行うのはJITerです。JITerにはデバッグ/リリースモードがあり、パフォーマンスに大きな違いをもたらします。プロジェクトのデバッグまたはリリース構成を実行し、デバッガーが接続されているかどうかを確認します。」

ソースは here で、ポッドキャストは here です。

誰かが実際にこれを証明できるマイクロソフトの記事に誘導できますか?

グーグル「C#debug vs release performance」は、「デバッグには多くのパフォーマンスヒットがあります」という結果を返します」、「リリースは最適化されています」、および「実稼働環境にデバッグを展開しないでください)。

130
sagie

部分的に正しい。デバッグモードでは、コンパイラはすべての変数のデバッグシンボルを出力し、コードをそのままコンパイルします。リリースモードでは、いくつかの最適化が含まれます。

  • 未使用の変数はまったくコンパイルされません
  • 一部のループ変数は、不変式であることが証明されると、コンパイラーによってループから取り出されます。
  • #debugディレクティブの下に記述されたコードは含まれませんなど。

残りはJIT次第です。

編集:最適化の全リスト ここ 礼儀 Eric Lippert

96
Adrian Zanescu

パフォーマンスに関する質問について「証明」する記事はありません。変更のパフォーマンスへの影響に関するアサーションを証明する方法は、両方の方法で試して、現実的だが制御された条件下でテストすることです。

あなたはパフォーマンスについて質問しているので、明らかにパフォーマンスに関心があります。パフォーマンスに関心がある場合、正しい目標は、パフォーマンス目標を設定し、それらの目標に対する進捗を追跡するテストスイートを自分で記述することです。このようなテストスイートを作成したら、それを使用して、「デバッグビルドが遅い」などのステートメントの真実性または誤りを簡単にテストできます。

さらに、意味のある結果を得ることができます。 「遅い」とは、1マイクロ秒遅いのか20分遅いのかわからないため、意味がありません。 「現実的な条件下で10%遅くなる」の方が意味があります。

この質問をオンラインで調査して、質問に答えるデバイスを構築することに費やした時間を費やしてください。そうすれば、はるかに正確な結果が得られます。あなたがオンラインで読むものは何でも推測何が可能性起こるかについてです。あなたのプログラムがどのように振る舞うかについて他人が推測したことではなく、あなたが自分で集めた事実からの理由。

62
Eric Lippert

パフォーマンスについてコメントすることはできませんが、大規模な製品ではデバッグコードが通常とはかなり異なることを行うため、「実稼働環境にデバッグを展開しない」というアドバイスは引き続き有効です。一つには、デバッグスイッチをアクティブにし、もう一つには、実稼働コードに属さない冗長な健全性チェックとデバッグ出力を追加する可能性があります。

10
Konrad Rudolph

msdn social から

十分に文書化されていませんが、ここに私が知っていることを示します。コンパイラは、System.Diagnostics.DebuggableAttributeのインスタンスを生成します。デバッグバージョンではIsJitOptimizerEnabledプロパティはTrue、リリースバージョンではFalseです。 ildasm.exeを使用して、アセンブリマニフェストでこの属性を確認できます。

JITコンパイラはこの属性を使用して、デバッグを困難にする最適化を無効にします。ループ不変の巻き上げのようにコードを移動するもの。特定のケースでは、これによりパフォーマンスに大きな違いが生じる可能性があります。通常はそうではありません。

ブレークポイントを実行アドレスにマッピングすることは、デバッガーの仕事です。 IL命令をコードアドレスマッピングに提供するJITコンパイラによって生成された.pdbファイルと情報を使用します。独自のデバッガを作成する場合は、ICorDebugCode :: GetILToNativeMapping()を使用します。

JITコンパイラの最適化が無効になっているため、基本的にデバッグの展開は遅くなります。

6
Neil

あなたが読んだものは非常に有効です。通常、リリースはデバッグコード(#IF DEBUGまたは[Conditional( "DEBUG")])を含まないJIT最適化により無駄が少なく、デバッグシンボルの読み込みが最小限で、多くの場合、アセンブリが小さいため読み込み時間が短縮されます。 VSでコードを実行すると、ロードされるより広範なPDBとシンボルのためにパフォーマンスの違いがより明確になりますが、独立して実行する場合、パフォーマンスの違いはそれほど明白ではない場合があります。特定のコードは他のコードよりも最適化され、他の言語と同じ最適化ヒューリスティックを使用しています。

スコットは、インラインメソッドの最適化について適切に説明しています here

この記事 を参照してください。ASP.NET環境でデバッグとリリースの設定が異なる理由を簡単に説明しています。

3
Fadrian Sudaman

パフォーマンスとデバッガーがアタッチされているかどうかに関して、注意する必要がある1つのことは、驚くべきことでした。

多くのタイトループを含むコードの一部があり、デバッグには永遠に時間がかかるように見えましたが、それ自体で非常にうまく動作しました。つまり、問題が発生している顧客やクライアントはいませんが、デバッグ中は糖蜜のように動作するように見えました。

犯人はDebug.WriteLineデバッグセッションからしばらく離れた数千のログメッセージを吐き出すタイトループの1つ。デバッガが接続されてそのような出力をリッスンすると、オーバーヘッドが発生してプログラムが遅くなるようです。この特定のコードの場合、ランタイムは0.2〜0.3秒程度で、デバッガーがアタッチされたときは30秒以上でした。

簡単な解決策ですが、不要になったデバッグメッセージを削除するだけです。

msdn site ...

リリースとデバッグの構成

プロジェクトでの作業中は、通常、デバッグ構成を使用してアプリケーションをビルドします。この構成により、変数の値を表示し、デバッガーで実行を制御できるためです。また、リリース構成でビルドを作成およびテストして、1つのビルドタイプまたは他のビルドでのみ現れるバグを導入していないことを確認できます。 .NET Frameworkプログラミングでは、このようなバグは非常にまれですが、発生する可能性があります。

アプリケーションをエンドユーザーに配布する準備ができたら、リリースビルドを作成します。リリースビルドは、対応するデバッグ構成よりもはるかに小さく、通常はパフォーマンスが向上します。ビルド構成は、プロジェクトデザイナのビルドペインまたはビルドツールバーで設定できます。詳細については、ビルド構成を参照してください。

2
hallie

デバッグモードとリリースモードには違いがあります。ツールがあります Fuzzlyn :Roslynを利用してランダムなC#プログラムを生成するファザーです。これらのプログラムを.NETコアで実行し、デバッグモードとリリースモードでコンパイルしたときに同じ結果が得られるようにします。

このツールで多くのバグが発見され、報告されました。

1
stokito

最近、パフォーマンスの問題に遭遇しました。製品の全リストには、80秒ほどの時間がかかりすぎていました。 DBを調整し、クエリを改善しましたが、違いはありませんでした。 TestProjectを作成することにしましたが、同じプロセスが4秒で実行されることがわかりました。その後、プロジェクトがデバッグモードであり、テストプロジェクトがリリースモードであることに気付きました。メインプロジェクトをリリースモードに切り替えたところ、すべての結果を表示するために製品の完全なリストに4秒しかかかりませんでした。

概要:デバッグモードは、デバッグ情報を保持するため、実行モードよりもはるかに低速です。常にリリースモードでデプロイする必要があります。 .PDBファイルを含めると、デバッグ情報を保持できます。これにより、たとえば、行番号でエラーを記録できます。

Lasseの例のように、大部分は、アプリがコンピューティングバウンドであるかどうかによって異なります。それが何をしているのかについて少し質問がある場合は、それを数回一時停止してスタックを調べます。私が本当に必要としなかった余分なことが起こっている場合、それはすぐにそれを見つけます。

0
Mike Dunlavey