1

try/catch はパフォーマンスが悪いと考えられていると聞いたことがありますが、例外をスローすることをめったに期待しない場合は、ブール値を持つメソッド/関数を使用するよりも、エラー情報を返すためのより良い方法と見なされます。

この方法で try/catch を使用すると、パフォーマンスが向上しますか? それは確かにコーディングを容易にします。

例:

void DoSomething(){
  try{
    DoSomethingIffy();
  } catch {
    // Yikes! Do failure stuff
  }
}

void DoSomethingIffy(){
  if (rareCondition) {
    throw new Exception("oops");
  }
}

void DoSomething(){
  if (!DoSomethingIffy()) {
    // Yikes! Do failure stuff
  }
}

bool DoSomethingIffy(){
  if (rareCondition) {
    return false;
  }
  else {
    return true;
  }
}
4

2 に答える 2

1

これは本当に状況によって異なります。一般に、Try/Catch は if/else よりもパフォーマンス ヒットが大きくなります (これも状況によって異なります) が、try/catch ブロックも適切なエラー処理の一部です。ベスト プラクティスとして (パフォーマンスとコードの保守性を向上させるため)、try/catch ブロックをより高いレベルに配置して、ブロックの数を制限することをお勧めします。たとえば、「Drive」メソッドを持つ「Car」という名前のクラスがあり、そのメソッドが Car.StartEngine() と Person.FastenSeatBelt() を呼び出す場合 (両方のメソッドで例外が発生する可能性があると想定)、try の代わりにStartEngine メソッド内の /catch と FastenSeatBelt メソッド内の別のキャッチ、

if/else を使用するか、try/catch を使用するかを決定する際に、さらに考慮すべき点があります。メソッド ConvertToCamelCase(string) があるとします。文字列パラメーターに null が渡された場合はどうしますか? 個人的には、このメソッドが ArgumentNullException をスローするようにしたいと考えています。次に、例外をログに記録または処理する必要がある場合は、呼び出し元のメソッドで try/catch ブロックを使用します。ただし、パラメーターが null であるかどうかに関係なく true/false を返すことにした場合は、このメソッドの名前を TryConvertToCamelCase(string) に変更することをお勧めします。この命名規則は、このメソッドから例外がスローされることを心配する必要がないことを呼び出し元に示唆しています。これは、何らかの理由で失敗した場合に false を返します。

考慮すべきもう 1 つのことは、「例外」を適切に処理して、現在のコードのセクションから続行できるかどうかです。たとえば、ユーザーが [開く] をクリックした後、テキスト ボックスで指定したファイルを単純に開く Windows フォームがあるとします。ボタン クリックのイベント ハンドラーでファイル処理を行う場合は、ファイルを開く処理のコードを if ステートメント内に配置し、条件を File.Exists にします。ファイルが存在しない場合は、else ブロックに移動し、ファイルが存在しないことをユーザーに知らせるメッセージ ボックスがポップアップ表示されます。しかし、イベント ハンドラーが代わりに私が作成したヘルパー クラスを使用した場合、それを「FileHelper」と呼びましょう。その場合、FileHelper の「ReadFile」メソッドは、ファイルが存在するかどうかを確認することさえ気にしません。それを開こうとするだけで、それができない場合は FileNotFoundException がスローされます。次に、ボタン クリック イベント ハンドラーが例外をキャッチし、ユーザーに警告します。これは、「FileHelper」クラスがフォームやユーザーの操作に関する知識を持たないためです。「ReadFile」メソッドがファイルを開くことができない場合は、続行する方法がないため、例外です。

最後に述べておきたいのは、エラーを処理するときに、それが予期したとおりのエラーであることを確認することです。多くの場合、開発者が「catch (Exception ex)」を実行してから、ユーザーにプロンプ​​トを表示してエラーを処理するのを目にします。しかし、以前の ReadFile メソッドを使用して、これを 32 ビット アプリとして実行していて、2 GB の制限のうち 1.9999 GB を既に消費しているとします。おそらく、「ex」は FileNotFoundException ではなく、実際には OutOfMemoryException です。ユーザーに「やあ、あのファイルは存在しない」と言って促すことは、実際にはユーザー エクスペリエンスを悪化させるだけです (そうするとは言っていませんが、私がよく目にすることです)。代わりに、「catch (FileNotFoundException ex) {...}」または「catch (Exception ex) { if (ex is FileNotFoundException) {...}」を使用できます。

まとめ: 例外をログに記録したり処理したりする必要がある場合は、try/catch を使用することを恐れないでください。

于 2013-09-06T03:49:06.707 に答える
1

スロー レートが 1 秒あたり 100 を超えている場合、または予想される場合は、パフォーマンスに影響を与える可能性があります。(「.NET Framework 設計ガイドライン:例外のスロー」を参照してください) この場合、コードの「ホット」な部分で例外をスローしない設計を使用すると効果的です。

これがコードのパフォーマンス クリティカル セクションである場合、1 秒間に 1,000,000 回入力する可能性があり、1,000 分の 1 のスロー確率は「まれ」かもしれませんが、パフォーマンスが許容できないほど低下する可能性があることを考慮してください。

現実的なユーザー シナリオでこれらのことを測定し、データを収集して、パフォーマンスの観点から、いずれかの設計が優れているかどうか (または、より複雑な設計を実装する価値があるかどうか) を知る必要があります。

データに関しては、.NET は例外に特に関連するパフォーマンス カウンターを提供します。これは、パフォーマンスの問題に直面した場合の診断に役立ちます。

于 2013-09-06T02:59:34.087 に答える