例外をスローしないトライアンドキャッチは条件付きよりも効率的ですか?


8

私は最近この例に出くわしました:

1,000回のうち999回の例外がスローされない場合、例外は1回だけ生成されます。一方、条件文は不必要に999回呼び出されているため、この場合は例外が優先されます。

このインスタンスではC#ですが、一般的に言ってこれは本当ですか?以前は、try / catchステートメントには、条件の処理に費やされる時間と同じ独自のオーバーヘッドがあると想定していました。

確かに、通常は条件付きの場所にtry / catchブロックを投げるだけでコードを書くのはひどい方法ですが、リソースの観点からこのステートメントは成り立ちますか?


コンパイラーはtry / catchをどのように実装しますか?単純なif()よりも少し複雑だと思います。
Dan Pichelman 2013

8
やってみて。本当に、試してみてください。なぜあなたはインターネット上の誰かが言ったと信じていますか?選択した言語の一般的な要素がパフォーマンスごとにどのように比較されるかを知ることは、注意深い実験を一度実行するという限られた努力の価値があります。
キリアンフォス2013

パフォーマンス比較を書くことは、特に抽象的なものを台無しにするのが非常に簡単な作業だと感じました。また、この例はC#の教科書からのものです
Jane Panda

2
必要な「可読コードを記述し、時期尚早に最適化しない」というコメントを付けます。
djechlin

1
@djechlin誰かがしなければなりませんでした。)
ジェーンパンダ

回答:


4

これは一般に、商用品質のコンパイラに当てはまります。ただし、assume(false)条件文は、-スタイルのアノテーションを使用して同様の効率を達成できます。プロファイルに基づく最適化は両方に勝る可能性があります。

根本的な理由は、優れたコンパイラは、実行されるコードの可能性について正しい仮定を行うことにより、より効率的なコードを生成できることです。例外は例外であるという慣例であるため、ほとんどのコンパイラー(プロファイリングデータがない場合)は、例外が実際にまれである場合に最適なコードを生成します。

たとえば、例外処理コードを独自のセグメントに配置し、最初の例外が発生したときにのみページインすることができます。つまり、CPUキャッシュをより効率的に使用して、例外的でないコードのみを保存できます。


そして、たとえばほとんどすべてのJavaScriptエンジン、JVM、Smalltalk実装に見られるような動的コンパイラーは、分岐の可能性について仮定する必要すらありません。それらは数えるだけです。これは、ステロイドのPGOのようなものです。現在実行中の実際のワークロードを使用して、現在実行中のコードを最適化するためのガイドとして、何度も何度もプロファイリングと再最適化を繰り返します
イェルクWミッターク

4

try / catchを使用するシナリオと、条件文を使用するシナリオがあります。

ここで広く概説されているように、try / catchを使用してもパフォーマンスに悪影響はありません。

例外を処理しないtry ... catchブロックの全体的なコストは、数バイトのメモリです。

パフォーマンスだけでなく、適切な例外処理も重要です。あなたが望む最後のものは、ユーザーに表示されているキャッチされていないエラー、バグのあるパフォーマンス、または問題が発生した後にアプリケーションがハングすることです。


3
心配する必要があるのは+1のパフォーマンスだけではありません。そうでなければ、ユーザーフレンドリーなグラフィカルインターフェイスを
破棄し

2
これは例外についての素晴らしい読み物です。
ジェーンパンダ

-1

条件の代わりにtry / catchを使用した場合のより良いパフォーマンスの例は、ディクショナリを処理するとき、キーを含むかどうかを尋ねるとき(O(n)と比べて)、単にキーにアクセス/追加して、潜在的な例外をキャッチするときです。

try
{
    dict.Add(key, val);
}
catch (Exception)
{

    dict[key] = val;
}

うわー、これが本当なら本当に驚いています!リファレンスはありますか?

5
-1。これを行わないでください。キーが存在するかどうかを確認することによるパフォーマンスのオーバーヘッドが心配な場合は、代わりにTryGetValue()を使用してください。msdn.microsoft.com/en-us/library/bb347013.aspx
riwalk 2013

それを指摘してくれてありがとう、私が欲しいのは少なくとも悪い習慣に助言することです。私はこれを長い間使用してきましたが、おそらく古くなった良い習慣だと思います。とにかく、私のポイントは、例外をキャッチする方が有効であるかどうかを尋ねるよりも良いオプションである可能性があるシナリオがあることを示すことでした。
エンリケメディナ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.