Эффективность исключения, когда ничего не выбрасывается

У меня есть гипотетический вопрос о последствиях эффективности использования обработки исключений в ситуациях, когда не выбрасываются исключения.

Сначала взгляните на этот С#:

int simpleSimon, cautiousCarol, dangerousDave;

try
{
    simpleSimon = int.Parse("fail");
}
catch
{
    simpleSimon = 1;
}

try
{
    cautiousCarol = int.Parse("1");
}
catch
{
    cautiousCarol = 1;
}

dangerousDave = int.Parse("1");

Я уверен, что код Дейва будет самым быстрым/самым эффективным; в то время как Саймон понесет большой штраф за исключение.

Но как насчет Кэрол? Поскольку она не исключает никаких исключений, она нести штраф? Если да, то какой и насколько большой? (Снижение производительности или дополнительное использование памяти или что-то еще?)

Ответ 1

Это деталь реализации JIT. Излучение x86 должно установить 16 байт в фрейме стека, чтобы помочь CLR найти правильный блок catch в случае возникновения исключения. Это займет около 3 наносекунд. Никакой работы вообще для джиттера x64, фильтрация исключений реализована по-разному в 64-разрядной версии Windows (вместо таблицы основаны на таблицах). Необходимая дополнительная память эквивалентна (код и данные таблицы).

Ничего из этого не должно иметь значения с таким кодом, что преобразование строки в целое является операцией ввода-вывода. Стоимость получения данных в первую очередь на 3 или 4 порядка больше, чем любой синтаксический анализ, который вы делаете. И вы, конечно, будете использовать TryParse(), если не доверяете источнику данных. Обработка исключения довольно дорого.

Ответ 2

Нет значительного штрафа за Carol. Только определенные скачки будут зарегистрированы и будут выполняться при необходимости.

В качестве подсказки используйте int.TryParse(...), чтобы избежать подобных ситуаций.