swap внутри функции для параметра-результата
От: sanx  
Дата: 01.03.13 19:28
Оценка:
Код 1:
bool func(const type &param, std::string &result)
{
    std::string s;
    // формируем/получаем s
    if (ok)
        result.swap(s);
    return ok;
}

И код 2
bool func(const type &param, std::string &result)
{
    std::string s;
    // формируем/получаем s
    if (ok)
        result.assign(s);
    return ok;
}

код 3
bool func(const type &param, std::string &result)
{
    // формируем/получаем используя result
    return ok;
}

Есть разница? Когда как лучше поступать?
Re: swap внутри функции для параметра-результата
От: Evgeny.Panasyuk Россия  
Дата: 01.03.13 19:53
Оценка: 1 (1) +1 -1
Здравствуйте, sanx, Вы писали:

S>Код 1:

S>
S>bool func(const type &param, std::string &result)
S>{
S>    std::string s;
S>    // формируем/получаем s  <--- Аллоцируется память
S>    if (ok)
S>        result.swap(s);  <--- быстрый swap
S>    return ok;
S>}
S>


S>И код 2

S>
S>bool func(const type &param, std::string &result)
S>{
S>    std::string s;
S>    // формируем/получаем s <--- Аллоцируется память
S>    if (ok)
S>    {
S>        result.assign(s); <--- строка копируется;
S>        в этот момент в памяти есть две одинаковые строчки: s == result
S>    }
S>    return ok;
S>}
S>

S>код 3
S>
S>bool func(const type &param, std::string &result)
S>{
S>    // формируем/получаем используя result <--- Память возможно даже не аллоцируется,
S>    а реиспользуется capcity из result
S>    return ok;
S>}
S>

S>Есть разница? Когда как лучше поступать?

В порядке убывания эффективности: 3, 1, 2.
Всегда(когда возможно) лучше исполользовать 3.
Без дополнительный ограничений(типа: не менять result при исключении) применений для 1, а тем более для 2 — не вижу.
Re: swap внутри функции для параметра-результата
От: Evgeny.Panasyuk Россия  
Дата: 01.03.13 20:12
Оценка: +1
И ещё: если у result была большая capacity: в первом случае — она "потеряется", во втором и третьем — "останется".
Так что тут ещё нужно учитывать общую стратегию — если необходимо что-то типа shrink_to_fit — то 1.
Re: swap внутри функции для параметра-результата
От: uzhas Ниоткуда  
Дата: 01.03.13 20:12
Оценка: +2
Здравствуйте, sanx, Вы писали:

S>Есть разница? Когда как лучше поступать?


Вот есть у меня банка сладкой кукурузы и банка зеленого горошка бондюэль
есть между ними разница? когда и что лучше скушать?
Re[2]: swap внутри функции для параметра-результата
От: sanx  
Дата: 01.03.13 20:29
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>Здравствуйте, sanx, Вы писали:


S>>Код 1:

S>>
S>>bool func(const type &param, std::string &result)
S>>{
S>>    std::string s;
S>>    // формируем/получаем s  <--- Аллоцируется память
S>>    if (ok)
S>>        result.swap(s);  <--- быстрый swap
S>>    return ok;
S>>}
S>>


S>>И код 2

S>>
S>>bool func(const type &param, std::string &result)
S>>{
S>>    std::string s;
S>>    // формируем/получаем s <--- Аллоцируется память
S>>    if (ok)
S>>    {
S>>        result.assign(s); <--- строка копируется;
S>>        в этот момент в памяти есть две одинаковые строчки: s == result
S>>    }
S>>    return ok;
S>>}
S>>

S>>код 3
S>>
S>>bool func(const type &param, std::string &result)
S>>{
S>>    // формируем/получаем используя result <--- Память возможно даже не аллоцируется,
S>>    а реиспользуется capcity из result
S>>    return ok;
S>>}
S>>

S>>Есть разница? Когда как лучше поступать?

EP>В порядке убывания эффективности: 3, 1, 2.

EP>Всегда(когда возможно) лучше исполользовать 3.
EP>Без дополнительный ограничений(типа: не менять result при исключении) применений для 1, а тем более для 2 — не вижу.

да, второй пункт я зря прилепил, понимаю так:
2-ой пункт использовать только если временный буфер из которого мы берем данные для результата — должен быть уничтожен при выходе из функции, например мы получили char* через api ОС и должны его скопировать и освободить.
3-ый пункт самый эффективный, но только если тот кто вызывает, использует result только как ответ, а не посылает в функцию какие-то нужные данные для обработки, которые должны сохраниться в случае неудачи
1-ый пункт — например bool tryFindAndFix(std::string &s); нужно обработать и вернуть измененные данные только в случае успеха, иначе не менять. swap обеспечивает дополнительную гарантию.

EP>Без дополнительный ограничений(типа: не менять result при исключении) применений для 1, а тем более для 2 — не вижу.

Является ли использование swap для библиотечной функции "правилом хорошего тона"? Ну типа не портить в случае ошибки? Или общее правило — делать эффективней, и судить так: если сама логика функции не преобразовывает, а отдает, то используем 3 пункт?
Re[2]: swap внутри функции для параметра-результата
От: sanx  
Дата: 01.03.13 20:37
Оценка: +1 :)
Здравствуйте, uzhas, Вы писали:

U>Здравствуйте, sanx, Вы писали:


S>>Есть разница? Когда как лучше поступать?


U>Вот есть у меня банка сладкой кукурузы и банка зеленого горошка бондюэль

U>есть между ними разница? когда и что лучше скушать?

Хороший кулинар может часами рассказывать интересные нюансы.
Ну может про часы я немного перегнул.
Re[3]: swap внутри функции для параметра-результата
От: Evgeny.Panasyuk Россия  
Дата: 01.03.13 21:06
Оценка: 2 (1)
Здравствуйте, sanx, Вы писали:

S>да, второй пункт я зря прилепил, понимаю так:

S>2-ой пункт использовать только если временный буфер из которого мы берем данные для результата —
[...]

Вроде бы всё верно.

EP>>Без дополнительный ограничений(типа: не менять result при исключении) применений для 1, а тем более для 2 — не вижу.

S>Является ли использование swap для библиотечной функции "правилом хорошего тона"? Ну типа не портить в случае ошибки? Или общее правило — делать эффективней, и судить так: если сама логика функции не преобразовывает, а отдает, то используем 3 пункт?

Судя по заданному интерфейсу, result — это чисто out параметр. Если это так, то в общем случае — не вижу причин для попыток сохранения его первоначальных значений.
Но всё же, нужно учитывать контекст использования этой функции — возможно она вызывается в цикле, и при ok==false — может понадобится старое значение.
В любом случае желательно задокументировать поведение.
Re[2]: swap внутри функции для параметра-результата
От: Evgeny.Panasyuk Россия  
Дата: 25.09.13 18:11
Оценка:
>>
>>bool func(const type &param, std::string &result)
>>{
>>    // формируем/получаем используя result <--- Память возможно даже не аллоцируется,
>>    а реиспользуется capcity из result
>>    return ok;
>>}
>>


Подобный вопрос(реиспользование capacity) обсуждался на Going Native 2013
Re: swap внутри функции для параметра-результата
От: Кодт Россия  
Дата: 25.09.13 19:37
Оценка:
Здравствуйте, sanx, Вы писали:

S>Есть разница? Когда как лучше поступать?

bool careless(string& result)
{
  result.clear();
  result += "mama ";
  if(rand()==13) return false; // "mama "
  result += "myla ";
  if(rand()==13) return false; // "mama myla "
  result += "ramu.";
  if(rand()==13) return false; // "mama myla ramu."
  return true; // "mama myla ramu."
}

bool transactional(string& result)
{
  string temp;
  temp += "mama ";
  if(rand()==13) return false; // "old value"
  temp += "myla ";
  if(rand()==13) return false; // "old value"
  temp += "ramu.";
  if(rand()==13) return false; // "old value"
  result.swap(temp);
  return true; // "mama myla ramu."
}

bool transactional_revised(string& result)
{
  string temp;
  temp.swap(result); // и обнуляем, и буфер повторно используем
  temp.clear();
  temp += "mama ";
  if(rand()==13) return false; // ""
  temp += "myla ";
  if(rand()==13) return false; // ""
  temp += "ramu.";
  if(rand()==13) return false; // ""
  result.swap(temp);
  return true; // "mama myla ramu."
}
Перекуём баги на фичи!
Re: swap внутри функции для параметра-результата
От: Tilir Россия http://tilir.livejournal.com
Дата: 26.09.13 10:44
Оценка:
Здравствуйте, sanx, Вы писали:

Верный подход зависит от того, имеет значение исходное состояние result или нет, то есть это

bool func(const type &param, std::string &result /* [out] */)


или

bool func(const type &param, std::string &result /* [in/out] */)


В первом случае result это мусорное значение и лучше всего approach 3 без дополнительных переменных:

.. do something with result buffer


Во втором случае если result осмыслен, то лучше транзакционная семантика approach 1:

std::string s;
.. do something with s
result.swap(s)


Тогда если в "do something using s" будет исключение, оно не испортит исходное значение result

---
With best regards, Konstantin
Re[3]: swap внутри функции для параметра-результата
От: zaufi Земля  
Дата: 26.09.13 19:41
Оценка:
Здравствуйте, sanx, Вы писали:

S>Здравствуйте, uzhas, Вы писали:


U>>Здравствуйте, sanx, Вы писали:


S>>>Есть разница? Когда как лучше поступать?


U>>Вот есть у меня банка сладкой кукурузы и банка зеленого горошка бондюэль

U>>есть между ними разница? когда и что лучше скушать?

S>Хороший кулинар может часами рассказывать интересные нюансы.

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

S>Ну может про часы я немного перегнул.
Re[4]: swap внутри функции для параметра-результата
От: Mr.Delphist  
Дата: 27.09.13 11:44
Оценка:
Здравствуйте, zaufi, Вы писали:

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


Ну как сказать — это зависит от акцентов. Если основная тема мероприятия — именно изысканое блюдо, то вино, как ни крути, будут подбирать под еду. Ну и наоборот.
Re[4]: swap внутри функции для параметра-результата
От: Кодт Россия  
Дата: 30.09.13 14:20
Оценка:
Здравствуйте, zaufi, Вы писали:

S>>Хороший кулинар может часами рассказывать интересные нюансы.

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

Это хороший метрдотель. А в это время, на кухне кулинар продолжает ездить по ушам официантке...
Перекуём баги на фичи!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.