私のゲームでは、チェックされるものがたくさんあり、インデックスが範囲外であることがよくあります。通常、物事が描画またはチェックされない場合でも問題ありません。現在、私のコードは読みやすいですが、デバッグ時に、ログに記録されている例外のためにゲームが1〜2フレーム失われます。ただし、VSの外部では正常に機能します。たくさんのif
ステートメントを使用して例外的な状況を回避しようとすると、コードの可読性が大幅に低下し、低いfps損失がなくなりました。他に効果はあるのでしょうか。
4 に答える
例外のスローは非常にリソースを消費します。if/thenステートメントまたはその他の「通常の」フロー制御を使用する方がはるかに高速です。
例外インスタンスを生成するには、例外がスローされた場所(スタックトレース)を特定するためにスタックウォークを実行する必要があるため、例外は主にコストがかかります。また、ガベージコレクターに余分な負荷がかかり、例外的な状況以外で例外を使用するには非常に貧弱な設計と見なされます。
try
さらに多くのsの代わりに多くのsを使用しても大丈夫if
ですか?
機能的なアプリケーションを作成するためにこれらのいずれかが必要な場合は、設計に問題がある可能性があります。例外的な状況は、一般的には例外的であり、ありふれたものではないと考えられています。
あなたが説明した状況(範囲外の指標)は明らかに例外ではありません。特に、大したことではないので例外を無視するからです。これは、そもそも例外が発生しないように努力する必要があるという大きなヒントです。
たくさんのifステートメントを使って例外的な状況を避けようとしたとき...
ご存知のように、多くのif
ステートメントは適切なアプローチではありません。読みにくく、論理エラーを隠す可能性があり、頭痛の種が増えるだけです。
代わりに、オブジェクトが最初から例外的な状態になるのを防ぐために、オブジェクトに明確に定義された個別の責任を与えることを検討してください。「たくさんの」if
ステートメントが必要な場合、オブジェクトは多くの条件をチェックしています。これは、おそらくそれらの責任が大きすぎることを意味します。
一般に、プログラムロジックの処理に例外が使用されないように、コードを記述してロジックを構造化する必要があります。状況によっては、例外を使用して、まれではあるが予想される条件を処理してもかまいません。ただし、例外は基本的にgoto
制御フローを非常に混乱させる可能性のあるステートメントであり、パフォーマンスが低いため、制御フローの例外は回避する必要があります。
あなたの場合、論理エラーを処理するために例外を使用することが適切であるようには思えません。実際、例外は、意図したとおりに実行しているように聞こえます。つまり、彼らはあなたのアルゴリズムが間違っているとあなたに言っています。
コードを注意深く見て、コードがスローされる理由を特定することをお勧めしますIndexOutOfBoundsException
。独自のパラメータの内部処理中にスローされた場合は、バグまたはアルゴリズムの設計が不十分である可能性があります。「このインデックスはどこから来たのですか?」と尋ねます。と「境界が設計に組み込まれ、後から付け加えられないようにアルゴリズムを作成する方法はありますか?」
例外を回避するために、常にコードを作成する必要があります。彼らは捕まえるのに非常に費用がかかります。
if
また、ネストされたステートメントをたくさん避ける必要があります。そうです、コードが読みにくくなります。
ステートメントが役立つ場合もありますswitch
が、例外やif
ステートメントを回避する方法は他にもたくさんあります。
たとえば、次の拡張メソッドを記述できます。
public static class Ex
{
public static void IfBounded<T>(this T[] @this, int index, Action<T> action)
{
if (@this == null) throw new System.ArgumentNullException("@this");
if (action == null) throw new System.ArgumentNullException("action");
if (index >= @this.GetLowerBound(0) && index <= @this.GetUpperBound(0))
{
action(@this[index]);
}
}
}
これで、次の種類のコードを記述できます。
var messages = new []
{
"Hello",
"Goodbye",
};
messages.IfBounded(-1, t => Console.WriteLine(t));
messages.IfBounded(0, t => Console.WriteLine(t));
messages.IfBounded(1, t => Console.WriteLine(t));
messages.IfBounded(2, t => Console.WriteLine(t));
この特定の拡張方法は状況に適していない可能性がありますが、このようなものを使用すると、コードが非常に簡潔で簡潔になる可能性があります。