Обработка исключений - PullRequest
       9

Обработка исключений

3 голосов
/ 07 декабря 2009

Я слышал, что люди говорят, что обработка исключений стоит немного дороже из-за разматывания стека.

Я что-то не получаю, разматывание стека происходит, выдает ли я исключение и использую ли я return. Так в чем же разница?

Если, например, у меня проблема с памятью, которую я не могу решить - единственный вариант - остановить функцию, пока я не достигну области, где проблема должна быть обработана или уведомлена. Так какой у меня другой вариант для исключения?

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

Объяснение будет приветствоваться.

Ответы [ 7 ]

7 голосов
/ 07 декабря 2009

Когда вы используете возврат, стек безусловно «разматывается», что концептуально может быть так же просто, как выполнение одной команды «ret» машинного кода. При исключениях при раскручивании стека необходимо искать подходящий обработчик исключений, что является гораздо более сложной задачей. Путь исключения также имеет задачу создания и, возможно, копирования объекта исключения, что может быть нетривиальным.

3 голосов
/ 07 декабря 2009

Разматывание стека отличается от простого возврата. Он также включает в себя поиск обработчика ошибок (блока catch) на каждом нижнем уровне в стеке. Вот что делает этот процесс тяжелым.

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

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

void MyMethod()
{
    try
    {
        Method1(); 
        Method2();
        Method3();
    }
    catch(SomeException const & e) // edited per Mordachai's suggestion
    {
       // handle SomeException
    }
    catch(SomeOtherException const & e)
    {
       // handle SomeOtherException
    }
}

void MyMethod()
{
    int err;
    err = Method1();
    switch(err)
    {
        case SOMEERRORCODE:
             // handle some error code
             break;
        case SOMEOTHERERRORCODE:
             // handle some other error code
             break;          
    }
    err = Method2();
    switch(err)
    {
        case SOMEERRORCODE:
             // handle some error code
             break;
        case SOMEOTHERERRORCODE:
             // handle some other error code
             break;          
    }
    err = Method3();
    switch(err)
    {
        case SOMEERRORCODE:
             // handle some error code
             break;
        case SOMEOTHERERRORCODE:
             // handle some other error code
             break;          
    }
}
2 голосов
/ 07 декабря 2009

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

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

1 голос
/ 07 декабря 2009

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

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

1 голос
/ 07 декабря 2009

Если вас интересует, как обработка исключений влияет на производительность, лучше всего начать с чтения Технического отчета о производительности C ++ (в частности, главы 5.4).

1 голос
/ 07 декабря 2009

Существует небольшая «стоимость» инфраструктуры, необходимая для передачи исключений. Раньше это было достаточно важно, многие люди предпочитали избегать этого и вообще отключать RTTI. В наши дни это настолько незначительно, что если это проблема, то, возможно, C ++ уже слишком высок для вас; -)

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

Большинство людей, которые жалуются на стоимость обработки исключений, думают о том, как это было раньше.

0 голосов
/ 07 декабря 2009

В большинстве версий обработки исключений добавляются небольшие накладные расходы, чтобы помочь компилятору справиться с такими проблемами, как область действия. Здесь - это статья с объяснением. Накладные расходы, о которых мы говорим, очень малы, и о них почти никогда не стоит беспокоиться.

...