2

例外のスローは遅いため、プログラムのフローを制御するために例外を使用しないようにと言われています。例外のスローが非常に遅い理由についての説明を聞いたことがありません。

質問は次のとおりです。

例外をスローするメカニズムと、パフォーマンスに影響を与える可能性のある特定の操作は何ですか?

編集:

いくつかの明確化: 例外のスローを処理するために、オペレーティング システムで必要な追加作業についてお聞きしたいと思います。ユーザーモードとカーネルモードの切り替えはそれほどコストがかかりますか? それとも、例外オブジェクトの構築にコストがかかるのでしょうか? それとも、私が見逃しているプログラムフローを切り替える何かがあるのでしょうか? 私の質問は、プログラミング言語にとらわれないものです (そう願っていますが、私が間違っていることを証明してください)。ただし、アンカーが必要な場合は、このトピックに関連する .NET 内部に最も関心があります。

EDIT2:

例外のパフォーマンスに問題はありません。このメカニズムの内部を理解したいだけです。

EDIT3:

私の質問をより明確にしました。

4

4 に答える 4

6

例外処理には、ある程度の複雑さと「魔法」が必要です。@Joni の応答を支持する主なコストは、スタック トレースを収集することです。例外がスローされると、ランタイムは互換性のある例外ハンドラーを探してスタックのアクティベーション レコードをたどる必要があり、最終的に実行すると各ステップがブロックされます。これはすべて実行時に発生する必要があります。コンパイラでは修正できません。C++ のような言語では、デストラクタを実行する必要があります。

例外処理は、基本的に帯域外の「例外的な」処理モードです。キャッシングなど、通常の実行を高速化するものも同様に機能しません。(ここでは、参照の局所性がはるかに悪いと思います)。この処理は最適化できますが、exc の処理は「特別」であると想定されているため、あまり注意が払われていません。

于 2013-06-29T15:40:53.783 に答える
4

例外はアプリケーション レベルで作成されます。それらに対するオペレーティング システムのサポートはありません。例外のスローとキャッチが、関数の呼び出しや関数からの戻りなど、他の非ローカルな制御の転送よりも遅くなる特別な理由はありません。

エラーコードを返す代替手段よりも例外を「遅く」するものは、プログラミング環境の詳細によって必要とされる追加の作業に依存します。たとえば Java では、例外をスローする最も遅い部分は、スタック トレースを埋めることです。

于 2013-06-29T13:56:02.443 に答える
2

あなたは誤解されていますが、実際のコードの結果はおそらくどちらの方法でも変わらないでしょう。.NET の例外処理システムは、実際には非常に高速です。つまり、そのパフォーマンスは、エラー処理の他のオプションに匹敵します。ただし、別の回答で述べたように、例外を適切に使用したいだけです。つまり、アプリケーションの通常の実行中に発生するとは予想されない例外的な状況に対してのみです。その理由は次のとおりです。

  • 例外を含むコード フローの分析は、例外を含まないコードよりも複雑であるため、「通常の」コードでは例外をスローしないようにする必要があります。
  • Visual Studio デバッガーは、例外がスローされるたびに報告します。出力ウィンドウには 1 行しかありませんが、例外を誤用すると、この素晴らしい機能はすぐに悪夢に変わります。
  • Visual Studio には、特定の種類の例外がスローされたときに中断する機能があります。一貫して例外を正しく使用する場合 (意図した目的のために、そのタイプの実際の例外を示すためだけに)、この機能は、エラー処理 (回復、レポートなど) に関連するアプリケーションのエラーをすばやくデバッグする方法を提供します。

実際の例外状況の処理に関して言えば、例外処理は実際には、エラー コードを返すなどの他のものよりもパフォーマンス上の利点を提供します。分岐予測とヒントに関して言えば、JIT はコードが例外をスローしないという仮定を立てることができるため、プロセッサの利用可能な分岐予測機能を効果的に使用するコードを生成して、エラー処理機能を含むコードの分岐オーバーヘッドを回避できます。しかし、積極的にエラーを処理していません。

于 2013-06-29T16:49:09.163 に答える