Исключения и производительность

Примечание.

Это содержимое перепечатывается разрешением Pearson Education, Inc. из руководства по проектированию платформы: соглашения, идиомы и шаблоны для повторно используемых библиотек .NET, 2-го выпуска. Этот выпуск был опубликован в 2008 году, и книга с тех пор была полностью пересмотрена в третьем выпуске. Некоторые сведения на этой странице могут быть устаревшими.

Одной из распространенных проблем, связанных с исключениями, является то, что если исключения используются для кода, который регулярно завершается ошибкой, производительность реализации будет неприемлемой. Это является действительной проблемой. Когда элемент выдает исключение, его производительность может быть на порядок ниже. Тем не менее можно достичь хорошей производительности, строго придерживаясь рекомендаций по исключениям, которые не допускают использование кодов ошибок. В двух шаблонах, описанных в этом разделе, предложены способы сделать это.

❌ НЕ используйте коды ошибок из-за опасений, что исключения могут негативно сказаться на производительности.

Повысить производительность можно с помощью шаблона Tester-Doer или Try-Parse, описанных в следующих двух разделах.

Шаблон Tester-Doer

Иногда производительность элемента, вызывающего исключение, можно улучшить, разбив его на два элемента. Рассмотрим метод Add интерфейса ICollection<T>.

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

Будет возвращен метод Add, если коллекция доступна только для чтения. В сценариях, когда ожидается, что вызов метода будет часто завершаться ошибкой, это может быть проблемой с производительностью. Один из способов устранения проблемы — проверить, является ли коллекция доступной для записи, прежде чем пытаться добавить значение.

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

Элемент, используемый для проверки условия, которое в нашем примере является свойством IsReadOnly, называется тестировщиком (tester). Элемент, используемый для выполнения операции, которая может приводить к исключениям (метод Add в нашем примере), называется исполнителем (doer).

✔️ Рассмотрите возможность использования шаблона Test-Doer для элементов, которые могут выдавать исключения в распространенных сценариях, чтобы избежать проблем с производительностью, вызванных исключениями.

Шаблон Try-Parse

Для API-интерфейсов, в которых очень важна производительность, следует использовать более быстрый шаблон, чем шаблон Test-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.

Фрагменты: © Корпорация Майкрософт (Microsoft Corporation), 2005, 2009. Все права защищены.

Перепечатано с разрешения Pearson Education, Inc. из книги Инфраструктура программных проектов. Соглашения, идиомы и шаблоны для многократно используемых библиотек .NET (2-е издание), авторы: Кржиштоф Цвалина (Krzysztof Cwalina) и Брэд Абрамс (Brad Abrams). Книга опубликована 22 октября 2008 г. издательством Addison-Wesley Professional в рамках серии, посвященной разработке для Microsoft Windows.

См. также