Подтвердить что ты не робот

Try..Catch блоки всегда дорогие?

Возможный дубликат:
Устраняются ли попытки/блокировать блоки, если исключения не выбрасываются?

Привет всем,  Просто быстрый вопрос о блоках try..catch. Я слышал, что они дороги для использования и не должны использоваться как часть потока программы. Однако для проверки адресов электронной почты я использую следующий код.

        try
        {
            MailAddress checkEmail = new MailAddress(testEmail);

            return true;
        }
        catch
        {
            return false;
        }

В связи с предшествующей проверкой я не исключаю исключения, если не попытается обойти проверку. Мой вопрос в том, что вы пытаетесь... Ловить блоки только дорого, если исключение поймано или оно всегда дорого, независимо от того, выбрано ли какое-либо исключение?

Спасибо

EDIT: Спасибо за все ответы. Я решил, что, поскольку проверка (на С#) не очень дорога, я буду придерживаться этого метода. Это происходит главным образом из-за того, что выбрасывается реальное исключение, поскольку есть предшествующие шаги проверки, которые гарантируют, что никто случайно не введет неверный адрес электронной почты.

4b9b3361

Ответ 1

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

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


¹ Более десяти лет назад я был ответственен за усовершенствования приложения .Net 1.1 "без сенсорного развертывания", в котором первое исключенное исключение заняло всего три секунды. Это было достаточной проблемой в одном случае использования открытия файла, который попросил пользователь, который, возможно, не был бы там, я должен был добавить проверку существования файла до того, как попытался открыть файл, что обычно является плохой практикой программирования (просто попробуйте открыть файл и обработать исключение, если это не удастся), только потому, что пользовательский опыт, ожидающий, что это исключение будет построено, было настолько бедным. Но это, вероятно, не тот мир, в котором мы живем сейчас.

Ответ 2

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

Я думаю, что исключения при неправильном вводе пользователя, как правило, неразумны. Исключения из памяти или другие неожиданные сбои в порядке.

Ответ 3

Просто, чтобы играть в адвоката дьявола - я нашел большое применение для использования Исключения для управления потоком: кнопка "Отмена".

Если у вас есть функция, запущенная на какой-то службе, которая может занять 10-120 минут, что делает кучу разных вещей, я обнаружил, что выполнение if (hasCanceled) запускает новое JobCancelledException() внутри моего Log() функция (которая регистрируется на каждом шаге, на котором я нахожусь), чтобы работать просто потрясающе. Он освобождается от текущего выполнения кода и прекращает выполнение задания - именно то, что мне нужно. Я уверен, что есть лучший способ сделать это, возможно, каким-то образом использовать события, но для моего случая он отлично работает (особенно потому, что задания не отменяются регулярно).

Другое тогда, хотя - я на 100% согласен с тем, что Исключения никогда не должны использоваться в качестве средства управления потоками.

@Kornel - У меня есть два слова для этого поста... Holy $hit =)

здесь простой пример псевдокода:

Class Job
{
       Public Run(param1,param2,etc...)
       {
             Try
            {
                   Log("Doing Something")
                   DoSomething()

                         Log("Doing Another")
                         DoAnother()

                         Log("This keeps going, etc, inside of these function we make the same Log calls where it makes sense")
                         Etc()
                   }
                   Catch(JobCancelledException)
                   {
                        status="Cancelled"
                   }
            }

              Private Log(ByVal str As String)
              {
                      MessateToUser(str)

                      if(hasCancelled)
                          throw new JobCancelledException
            }

             private SomeEvent_WhenUserPushesCancelButton()
             {
                       hasCancelled=True
             }
}

Ответ 4

try..catch блоки никогда не должны использоваться в качестве инструмента управления потоками программ.

Прочитайте этот поток, если вы не уверены.

Ответ 5

Исключения стоят только дорого, если вызывается исключение. Я уверен, что есть некоторые очень минимальные затраты на создание блока Try..Catch, но он значительно перевешивается из-за того, что вы вообще не поймаете исключение и не потерпите крах вашей программы. Как указывали другие, Try..Catch блоки должны использоваться только для исключительных обстоятельств.

Ответ 6

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

Ответ 7

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

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

string invalidAddress = "[email protected]@@@@@lolzors.bomb";
return MailAddressValidator.IsValid(invalidAddress ); // doesn't cause exception

Исключение из правила заключается в том, что вам нужно будет свернуть собственную версию сложного метода (например, что-то, найденное в библиотеке базового класса, которое не имеет метода TryParse), чтобы избежать исключения, в великой схеме вещей просто не имеет значения.

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

Ответ 8

В общем, современные компиляторы налагают только минимальные затраты на блоки try, если не будет выбрано исключение. Они по-прежнему не должны использоваться для управления потоком программ, поскольку они не столь очевидны, как стандартные поточные конструкции. Исключение по существу эквивалентно оператору COME FROM.

Ответ 9

Хотя верно, что вы никогда не должны использовать try..catch для управления потоком программ, я не знаю о каких-либо проблемах с производительностью, если в коде действительно нет исключений

Ответ 10

Это зависит от языка, но, насколько я знаю на Java, если исключение не выбрасывается, стоимость выполнения try/catch не будет ниже стоимости.

Итак, в вашем примере использования предварительно подтвержденных адресов электронной почты у вас все в порядке.