Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Безопасность исключений, и потеря производительности (да или нет) 
V
    Опции темы
 
Когда стоит делать функцию строго-безопасной за счет производительности
Стараться делать всегда [ 2 ]  [10.53%]
Только когда это явно требуется [ 12 ]  [63.16%]
Никогда! [ 2 ]  [10.53%]
Свой вариант [ 3 ]  [15.79%]
Всего проголосовавших: 19
В этом опросе возможен один вариант ответа
Гости не могут голосовать 
azesmcar
Дата 9.9.2010, 08:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 81
Всего: 211



Добрый день,

Допустим мы пишем функцию-член, в которой происходит трансформация вектора из строк.
Код

class X
{
public:
    /* ... */
    void transform();
private:
    std::vector<std::string> data;
};

Код


void X::transform()
{
    std::transform(data.begin(), data.end(), data.begin(), std::bind2nd(std::plus<std::string>(), "A"));
}

Эта функция не гарантирует строгой безопасности, так-как если вдруг оператор + класса string для 4-ого объекта в векторе сгенерирует исключение, то первые три будут модифицированы, и класс изменит свое состояние. Исправить это легко
Код

void X::transform()
{
    std::vector<std::string> temp(data);
    std::transform(temp.begin(), temp.end(), temp.begin(), std::bind2nd(std::plus<std::string>(), "A"));
    data.swap(temp);
}

но этот вариант намного медленнее.
Если отбросить те моменты, где строгая безопасность исключений явно необходима, то в остальных случаях код подобного рода смахивает на паранойю. Скажем оператор + может сгенерировать bad_alloc, в принципе в этом случае вообще можно наплевать на то, что случиться с программой, все равно продолжать работать в таком состоянии будет невозможно, тут главное помереть с достоинством.
В общем вопрос в том, стоит ли стараться давать строгую гарантию безопасности исключений за счет производительности, в тех случаях, когда этого явно не требуется. И в каких вообще случаях стоит это делать?

Спасибо.

Добавлено через 1 минуту и 57 секунд
Забыл сказать, я за вариант "Только когда это явно требуется".
PM   Вверх
mes
Дата 9.9.2010, 09:06 (ссылка) |    (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(azesmcar @  9.9.2010,  07:51 Найти цитируемый пост)
    std::vector<std::string> temp(data);
    std::transform(temp.begin(), temp.end(), temp.begin(), std::bind2nd(std::plus<std::string>(), "A"));
    data.swap(temp);


Цитата(azesmcar @  9.9.2010,  07:51 Найти цитируемый пост)
но этот вариант намного медленнее.

 
а если таk, то ненамного :
Код

   std::vector<std::string> temp(data.size());
   std::transform(data.begin(), data.end(), temp.begin(), std::bind2nd(std::plus<std::string>(), "A"));
   data.swap(temp);

 smile 

Это сообщение отредактировал(а) mes - 9.9.2010, 09:09


--------------------
PM MAIL WWW   Вверх
azesmcar
Дата 9.9.2010, 09:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 81
Всего: 211



Цитата(mes @  9.9.2010,  09:06 Найти цитируемый пост)
а если таk, то ненамного :

Да, но все равно медленнее (одного дополнительного выделения памяти достаточно), имелась ввиду сама мысль smile 

PM   Вверх
borisbn
Дата 9.9.2010, 10:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 22
Всего: 135



Цитата(mes @  9.9.2010,  09:06 Найти цитируемый пост)
Это сообщение отредактировал(а) mes - 9.9.2010,  09:09

специально дожидался этого времени ? smile
Цитата(azesmcar @  9.9.2010,  08:51 Найти цитируемый пост)
Забыл сказать, я за вариант "Только когда это явно требуется".

поддерживаю. в данном случае ( std::bind2nd(std::plus<std::string>(), "A") ) это действительно похоже на параною, а вот если там будет, например, вызов функции из dll-ки плагина, то это - вполне оправдано.


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
azesmcar
Дата 9.9.2010, 10:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 81
Всего: 211



borisbn

Речь не только про исключение bad_alloc. Есть категория исключений, с которыми в большинстве случаев вообще не знаешь что делать. bad_alloc - хороший пример из этой категории. Вопрос на самом деле немного более запутанный. Углубимся в детали smile 

допустим мы разрабатываем класс X, который будет проделывать некоторую работу. Класс будет использован нами и возможно в дальнейшем еще кем-то другим, из своей же компании. Поскольку безопасность исключений нельзя оставлять на потом (это может затронуть интерфейс класса) об этом надо подумать заранее. Функция transform нас вполне устраивает и базовой гарантии нам более чем достаточно в нашем конкретном случае, но кто знает в каком контексте будет использован класс Х другими программистами? А если то, что сегодня кажется паранойей завтра кому-то другому может понадобиться? Смысл в том, думать ли о будущем, жертвовать производительностью программы, если на данный момент это не нужно?

Немного изменим пример, сделаем класс X шаблонным. Теперь в него можно передавать любой тип, и то, что кажется паранойей (исключение из оператора +) для класса string может запросто стать обычным явлением в каком нибудь классе A, хотя на сегодняшний день использование класса X с таким типом не предполагается. Но если посмотреть для примера библиотеку STL она для большинства классов дает строгую гарантию безопасности исключений, для большинства, но не для всех и скорее всего из соображений производительности.

Это сообщение отредактировал(а) azesmcar - 9.9.2010, 10:49
PM   Вверх
bsa
Дата 9.9.2010, 10:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



azesmcar, обычно, это решается путем указания в документации всех известных подводных камней. Т.е. в твоем случае, ты можешь указать, что в случае возникновения исключения класс окажется в неизвестном состоянии. Поэтому использующий его хороший программист будет это уже иметь в виду.
PM   Вверх
xvr
Дата 9.9.2010, 10:51 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 60
Всего: 223



Свой вариант - нужно обеспечить, что бы при возникновении исключения не происходило утечек ресурсов и класс (откуда оно вышло) остался в consistent состоянии (т.е. не развалился при его дальнейшем использовании). Отслеживать, что бы класс остался в ПРАВИЛЬНОМ состоянии не требуется, т.к. совершенно непонятно, что под этим ПРАВИЛЬНОМ состоянием понимать.
Т.е. если возьмем исходный пример -
Код

void X::transform()
{
    std::transform(data.begin(), data.end(), data.begin(), std::bind2nd(std::plus<std::string>(), "A"));
}
то он получается безопасным, т.к. хотя data и будет модифицирован, но с ним (модифицированным) можно будет работать и дальше.
Если этот метод отработает до конца (без исключений), data в любом случае будет модифицирован. И нет никакого смысла при возникновении исключения где то посередине работы все откатывать в первоначальное состояние.
Исключение в принципе сигнализирует об ошибке где то в процессе выполнения, и изменение части массива data можно считать частью этой возникшей ошибки

PM MAIL   Вверх
bsa
Дата 9.9.2010, 10:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



Цитата(azesmcar @  9.9.2010,  11:27 Найти цитируемый пост)
если посмотреть для примера библиотеку STL она для большинства классов дает строгую гарантию безопасности исключений, для большинства, но не для всех и скорее всего из соображений производительности.

Думаю, это сделано не для того, чтобы гарантировать тебе безопасность, а просто так получилось при проектировании (т.е. оптимальный алгоритм это гарантирует, а другие - менее эффективны, поэтому не рассматриваются). Или просто необходимо, так как возможное "неизвестное состояние" может привести к краху программы.
PM   Вверх
azesmcar
Дата 9.9.2010, 11:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 81
Всего: 211



xvr

Цитата(xvr @  9.9.2010,  10:51 Найти цитируемый пост)
нужно обеспечить, что бы при возникновении исключения не происходило утечек ресурсов и класс 

Это базовая гарантия, это само собой как минимум.

http://en.wikipedia.org/wiki/Exception_guarantees
Цитата

    * The strong guarantee: that the operation has either completed successfully or thrown an exception, leaving the program state exactly as it was before the operation started.
    * The basic guarantee: that the invariants of the component are preserved, and no resources are leaked. Often referred to as the weak guarantee, because following an exception the system is left in a safe but unknown state.
    * The no-throw guarantee: that the operation will not throw an exception.

тема про "strong guarantee".

Цитата(bsa @  9.9.2010,  10:51 Найти цитируемый пост)
azesmcar, обычно, это решается путем указания в документации всех известных подводных камней. Т.е. в твоем случае, ты можешь указать, что в случае возникновения исключения класс окажется в неизвестном состоянии. Поэтому использующий его хороший программист будет это уже иметь в виду. 

в документации естественно это должно указываться smile , но вопрос в том, как делать, т.е. ответ - не делать.

PM   Вверх
djamshud
Дата 9.9.2010, 11:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Пердупержденный
***


Профиль
Группа: Завсегдатай
Сообщений: 1655
Регистрация: 23.11.2009

Репутация: 8
Всего: 39



Я обычно стараюсь избегать таких ограждений. Только если отдаю на модификацию какие-то важные данные, которые могут понадобиться даже после того, как программа начала умирать. В целом это очень редко, так что ответ между "по требованию" и "никогда!", но ближе к "никогда".


--------------------
'Cuz I never walk away from what I know is right
Alice Cooper - Freedom
PM   Вверх
xvr
Дата 9.9.2010, 12:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 60
Всего: 223



Цитата(azesmcar @  9.9.2010,  11:19 Найти цитируемый пост)
Это базовая гарантия, это само собой как минимум.
...
тема про "strong guarantee".

В таком случае будет вариант 2, плавно перетекающий в вариант 3, т.к. лично я не очень вижу массы мест (точнее вообще их не вижу  smile  ), где ТРЕБУЕТСЯ strong guarantee, а не достаточно просто basic guarantee

PM MAIL   Вверх
azesmcar
Дата 9.9.2010, 13:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 81
Всего: 211



Цитата(xvr @  9.9.2010,  12:10 Найти цитируемый пост)
точнее вообще их не вижу

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

Интересно, а кто это ЗА 1-ый вариант и без комментариев?

PM   Вверх
xvr
Дата 9.9.2010, 13:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 60
Всего: 223



Цитата(azesmcar @  9.9.2010,  13:20 Найти цитируемый пост)
тогда было бы желательно вернуть ему первозданный вид
Ну это можно рассматривать как специфичную разновидность утечки ресурсов (ресурс - это не только память). Так что это скорее ближе к basic guarantee



PM MAIL   Вверх
azesmcar
Дата 9.9.2010, 13:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 81
Всего: 211



Цитата(xvr @  9.9.2010,  13:39 Найти цитируемый пост)
Ну это можно рассматривать как специфичную разновидность утечки ресурсов (ресурс - это не только память). Так что это скорее ближе к basic guarantee

в принципе да, но скажем оставленный lock-нутым мьютекс не назовешь утечкой ресурсов.
PM   Вверх
bsa
Дата 9.9.2010, 13:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



azesmcar, ты же не маленький, ты сам все понимаешь, что мы подразумеваем под "basic", а что под "strong". Естественно, мьютексы и железки надо возвращать в исходное состояние. Более того, тут скорее всего никакого оверхеда по производительности не возникает (только немного по коду). А вот то, о чем ты говорил в первом посте (strong), это уже совсем другое - это значительный оверхед. Более того, местами совершенно ненужный. Поэтому, пользователь твоего класса узнав, что ему предоставляется только basic, уже сам должен решать как поступать дальше - добавлять код для получения strong или нет. Твоя задача, не ставить преграды на его пути (т.е. сделать все необходимое, чтобы он мог воспользоваться стандартной схемой: создать копию, изменить ее, сделать swap с оригиналом)...
PM   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0678 ]   [ Использовано запросов: 24 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.