16

一般に、共通のハンドラを持つ複数の障害ポイントを持つコードには、try/catch を使用する傾向があります。

私の経験では、これは通常、何らかのアクションを実行する前に入力またはコンテキストを修飾するか、何らかのアクションを実行した後に出力を修飾するコードです。

そのようなブロック内のコードを最小限に抑えるように文献や同僚からアドバイスを受けており、一般的には良いアドバイスとして受け入れています。

上記のアドバイスの基礎についてもう少し理解したいと思います。

  • オーバーヘッドの性質は何ですか?
  • try/catch ブロックの推奨される使用 (または回避) に対処する最近の開発ガイドラインはありますか?
  • より高速なプロセッサーと最新のコンパイラーは、try/catch の問題をどの程度軽減しますか?

助けてくれてありがとう、

AJ

4

8 に答える 8

18

C++ では、コストは実装によって異なります。一般に、例外を実装するには 2 つの方法があります。

1 つ目は「テーブル」アプローチです。コンパイラは、例外がスローされた時点で検索するテーブルのセットを構築します。例外がスローされると、この例外をキャッチするものが見つかるまで、コール スタックの各テーブルを検索する必要があります。これはすべて実行時ベースであるため、try catch に入ったり出たりしてもペナルティは発生しませんが (良いことです)、例外をスローすると多くのルックアップが必要になる可能性があり、スローが大幅に遅くなります。例外は非常にまれな状況であるため、私は個人的に try catch ブロックに料金を支払う必要がないことを好みます。これにより、テーブルを格納する必要がある場合、実行可能ファイルも大きくなります。

秒は「コード」アプローチです。コードが try catch ブロックに入るたびに、概念的には、ブロックの場所がスタックにプッシュされます。これにより、try-catch ブロックに出入りする際にコストが発生しますが、例外がスローされると、ランタイム メカニズムはスタックからすぐにポップして移動先を見つけることができます。したがって、例外のスローは (はるかに?) 高速ですが、ブロックに入るにはコストがかかります。try catch ブロックをタイトな低レベル ループに配置すると、かなりのオーバーヘッドが発生する可能性があります。

特定のコンパイラをチェックして、使用するコンパイラを確認する必要があります。

于 2009-06-04T17:41:35.940 に答える
7

例外に関するセクションを含むC++ のパフォーマンスに関するテクニカル レポート(pdf 警告)を見つけました。面白いと思うかもしれません。try/catch ブロック内のすべての命令にオーバーヘッドがあると信じている同僚がいましたが、このテクニカル レポートはその考えを支持していないようです。

于 2009-06-04T16:12:46.543 に答える
5

2 番目の質問: 一般的なガイドラインはこちらです。Herb Sutter もこちらで適切なアドバイスを提供ています。

于 2009-06-04T16:05:12.563 に答える
2

コンパイラに依存します。try-catchブロックを使用した単純な関数と、それを使用しない同様の関数を作成して、生成されたマシンコードを比較してみませんか?

于 2009-06-04T17:24:27.727 に答える
0

C ++では、クリーンアップを実行するためにtry/catchブロックを使用しないでください。代わりに、テンプレートを使用してリソースの取得を実行することをお勧めします。

auto_ptrは1つの[悪い]例です

同期ロック。ミューテックスを状態変数として格納し、ローカル変数(テンプレートまたは通常のクラス)を使用して.acquire()/。release()メソッドを実行します。

これを実行すればするほど、例外的な条件でオブジェクトを手動で解放することを心配する必要が少なくなります。C++コンパイラがそれを行います。

于 2009-06-04T19:42:48.243 に答える
0

ほとんどの言語では、通常のメソッドを介して try/catch ブロックに出入りするのは自由です。例外がスローされたときだけ、例外ハンドラーが例外を処理する場所を検索します。

于 2009-06-04T16:15:25.887 に答える
0

私の経験では、try/catch ブロックの最大の問題は、例外を一般的にキャッチしようとすることが多いことです。たとえば、(...) をキャッチする try/catch ブロックでメイン関数をラップすると、基本的に、スローされた例外の b/c をプログラムがクラッシュさせないようにしています。

私が見ているように、このアプローチの問題は2つあります。1) テストとデバッグを行っている間、エラーは表示されず、エラーを修正する機会もありません。2) それは本当に怠惰な方法を取るようなものです. 発生する可能性のある問題を考えて、エッジケースが何であるかを理解する代わりに、失敗しないようにしています. 失敗しないようにすることは、成功しようとすることとは大きく異なります。

于 2009-06-04T16:05:00.473 に答える