例外とパフォーマンス

Note

このコンテンツは、Pearson Education, Inc. の許可を得て、『Framework Design Guidelines: Conventions, Idioms, and Patterns for Reusable .NET Libraries, 2nd Edition (フレームワーク設計ガイドライン: 再利用可能な .NET ライブラリの規約、表現形式、およびパターン、第 2 版)』から転載されています。 この版は 2008 年に出版され、その後、この本は第 3 版で全面的に改訂されました。 このページの情報の一部は以前のものである可能性があります。

例外に関する一般的な懸念の 1 つとして、日常的に失敗するコードに例外を使用すると、実装のパフォーマンスが許容できないものになるだろうということがあります。 これはもっともな心配です。 メンバーによって例外がスローされる場合、そのパフォーマンスが桁違いに低下する可能性があります。 ただし、エラー コードの使用を禁止する例外ガイドラインに厳密に準拠しながら、優れたパフォーマンスを達成することができます。 このセクションで説明する 2 つのパターンは、これを行う方法を提案しています。

❌ 例外によるパフォーマンスへの悪影響の可能性が心配であるという理由で、エラー コードを使用しないでください。

パフォーマンスを向上させるために、次の 2 つのセクションで説明する、Tester-Doer パターンまたは Try-Parse パターンを使用できます。

Tester-Doer パターン

例外をスローするメンバーを 2 つに分割することで、メンバーのパフォーマンスを向上させることができる可能性があります。 ICollection<T> インターフェイスの Add メソッドを見てみましょう。

ICollection<int> numbers = ...
numbers.Add(1);

コレクションが読み取り専用の場合、メソッド Add によって (例外が) スローされます。 これは、このメソッドの呼び出しが頻繁に失敗することが予想されるシナリオでは、パフォーマンスの問題になる可能性があります。 この問題を軽減する方法の 1 つは、値を追加する前に、コレクションが書き込み可能かどうかをテストすることです。

ICollection<int> numbers = ...
...
if (!numbers.IsReadOnly)
{
    numbers.Add(1);
}

条件をテストするために使用されるメンバー (この例では IsReadOnly プロパティ) を Tester と呼びます。 可能性があるスロー操作を実行するために使用されるメンバー (この例では Add メソッド) を Doer と呼びます。

✔️ 例外に関連するパフォーマンスの問題を回避するために、一般的なシナリオで例外をスローする可能性のあるメンバーに対して Tester-Doer パターンを使用することを検討してください。

Try-Parse パターン

パフォーマンスが非常に重要な API では、前のセクションで説明した Tester-Doer パターンよりも高速なパターンを使用する必要があります。 このパターンでは、メンバー名を調整して、適切に定義されたテスト ケースをメンバー セマンティクスの一部にするための呼び出しが行われます。 たとえば、DateTime では、文字列の解析が失敗した場合に例外をスローする Parse メソッドが定義されます。 解析を試行する対応する TryParse メソッドも定義されますが、解析が失敗した場合は false が返され、解析が成功した場合はその結果が out パラメーターを使用して返されます。

public struct DateTime
{
    public static DateTime Parse(string dateTime)
    {
        ...
    }
    public static bool TryParse(string dateTime, out DateTime result)
    {
        ...
    }
}

このパターンを使用する場合は、Try 機能を厳しい条件で定義することが重要です。 明確に定義された Try 以外の理由でメンバーが失敗した場合でも、メンバーによって対応する例外がスローされる必要があります。

✔️ 例外に関連するパフォーマンスの問題を回避するには、一般的なシナリオで例外をスローする可能性のあるメンバーに対して Try-Parse パターンを使用することを検討してください。

✔️ このパターンを実装するメソッドには、"Try" というプレフィックスとブール型の戻り値を使用してください。

✔️ Try-Parse パターンを使用して、メンバーごとに例外をスローするメンバーを用意してください。

Portions © 2005, 2009 Microsoft Corporation. All rights reserved.

2008 年 10 月 22 日に Microsoft Windows Development シリーズの一部として、Addison-Wesley Professional によって発行された、Krzysztof Cwalina および Brad Abrams による「Framework Design Guidelines: Conventions, Idioms, and Patterns for Reusable .NET Libraries, 2nd Edition」 (フレームワーク デザイン ガイドライン: 再利用可能な .NET ライブラリの規則、用法、パターン、第 2 版) から Pearson Education, Inc. の許可を得て再印刷されています。

関連項目