0

デバッガーを接続した状態でアプリの実行が非常に遅いのはなぜかと少し時間をかけて考えたところ、これは条件付きブレークポイント(条件が満たされない)が原因であることがわかりました。CPUはブレークポイントを通知し、VSは実行を続行する前に条件を評価する必要があるため、これは妥当なようです。これらの移行にはコストがかかる必要があります。

実行されないコードパスのブレークポイントは、実行時に影響を与えないと思います。

だから私の質問は2つあります:

  1. 条件付きブレークポイントに関連するコストを定量化できるリソースはありますか?もしそうなら、実行時評価コストを削減するためにできることはありますか?
  2. 'disabled'ブレークポイントに関連するコストはありますか?無効とは、VSが中空の円で側溝にブレークポイントマーカーを表示することを意味します。

もちろん、私が上で述べたことが意味をなさない場合は、正しい方向に私を向けてください。

4

5 に答える 5

5

条件付きブレークポイントのコストを定量化するのは困難です。条件付きブレークポイントの式は、ウォッチウィンドウまたはイミディエイトウィンドウに入力した場合とまったく同じセマンティクスを使用して評価されます。この性質の式は、実際にはクライアントプログラムで実行されるのではなく、言語固有の式エバリュエーターによって処理されます。これらのタイプの評価を意味のある方法でプロファイリングすることは実際には不可能です。

ただし、デバッグウィンドウの評価で遅いことがわかっているものをいくつかリストできます

  • 関数呼び出し:関数呼び出しでは、関数呼び出しがプロセスで発生するようにdebuggeeプロセスを再起動する必要があるため、実行できる最も遅い処理です。
  • 文字列の比較:内部では、これらは関数評価に戻ります

無効なブレークポイントについては、アプリケーションの実行には影響しません。

于 2009-10-19T15:55:32.687 に答える
2

注意すべきことの1つ(私は難しい方法を学びました)は、変数を単一の=ではなく値と比較するときに==を置くようにすることです。

ブレークポイントエディタは警告を表示しませんが、ブレークポイントが評価されると、変数が変更されます。それを使ってコードをデバッグするのに少し時間がかかりました!

また、コードをバグにするために条件付きブレークポイントが本当に必要な場合は、コードに条件を追加してから、string stop="here";のようなものを追加します。そこに通常のブレークポイントを配置します-コードの実行速度が速いことがわかりました。

于 2010-06-09T14:16:52.043 に答える
0

これらのブレークポイントのハードウェアサポートがあることをどこかで読んだので、特定の種類のx未満の条件付きブレークポイントの使用は基本的に無料ですが、それ以上の場合は、より多くのソフトウェアを使用する必要があります。(OTOH、それはネイティブアプリ用でしたが、これらの新しいJITのことについてはよくわかりません。)

無効にされたブレークポイントは、すべてに影響を与えるはずです。それらは、IDEの一部のメモリとGUIリソースを占有するだけです。

于 2009-10-19T15:54:16.327 に答える
0
  1. コードにブレークポイントを設定して、パフォーマンスをテストしてみてください。例えば

    Stopwatch st = new Stopwatch();
    st.Start();
    if(my condition)
    {
      st.Stop();
      Debugger.Break();
    }
    

    いいえ、まったく同じではありませんが、十分に近いです。

  2. いいえ-無効なブレークポイントは実行中のプログラムに存在しません。便宜上、VSメタデータに保存されるだけです。

于 2009-10-19T15:55:03.750 に答える
0

また、条件付きブレークポイントは高価であり、あなたと同じ結論に達したことに気づきました。ブレークポイントを無効にすると速度が低下する理由は想像できません。これはエディターのみのものであり、必要に応じてブレークポイントをオンにするためのショートカットであると予想されるためです。

私があなたのような状況にあるときに私がすることは、assertマクロを作成することです。(Visual Studioが提供するassertマクロを使用できますが、私はそれが好きではありません)。マクロに必要な条件をチェックさせ、失敗した場合はDebugBreakを呼び出します。アプリケーションのリリース、またはチェックされていないビルドでは、assertは何も評価されないため、コードは影響を受けません。

単純なアサートマクロは次のようになります。

#ifdef _DEBUG
#define assert(x)\
do{\
  if(!(x)){DebugBreak();}\
}while(0)
#else
#define assert(x)
#endif

そしてそれを次のように呼びます:

assert(pValue != NULL && "A bad parameter was passed to the function");

DebugBreakの前に失敗にさらにコードを入れることができます(#xで失敗した条件、および/またはメッセージをダブルクリックできるように____FILE____と____LINE ____で行/ファイル番号を出力するなど)。OutputDebugStringを使用してデバッグログにメッセージを書き込み、さらにデバッガーがIsDebuggerPresentに接続されているかどうかを確認して、アサーションをさらに調整することができます。また、&&文字列形式を使用して、特定のアサーションに関するもう少し情報を提供するのも好きです。

assertを使用する際に注意すべき点がいくつかあります。まず、非デバッグビルドで削除されるため、マクロで実行する必要のあるコードを配置しないでください。同じ理由で、副作用のあるコードを入れないでください。また、デバッガーが接続されていないときにDebugBreak()を呼び出さないでください。これは、デバッガーが本質的に例外をスローし、キャッチされない場合はアプリケーションを終了するためです。

于 2009-10-19T16:13:55.943 に答える