Вопрос

У меня есть функция, которая выглядит так:

// Fetch 1 MB of data
void GetData(std::vector<char> & outData);

1 МБ преувеличен, но я просто хочу подчеркнуть, что предпочтительнее избегать ненужных копий.

Если я добавлю эту перегрузку:

std::vector<char> GetData()
{
    std::vector<char> result;
    GetData(result);
    return result;
}

Тогда как вероятно, что RVO начнет?

Это было полезно?

Решение

С большинством достаточно недавних компиляторов (например, VS 2005 или новее, GCC 3.4 или новее), это по сути определенно. Я только говорю «большинство», потому что я не тестировал каждый компилятор в существовании. Каждый новый компилятор, на котором я посмотрел, вероятно, последние 5 лет, или так включил его.

Другие советы

RVO, скорее всего, будет пинать, поскольку это довольно простая оптимизация, которая была доступна довольно долго. Однако для того, чтобы дать этот кусок кода реальную практическую ценность в даже умеренно высокопроизводительном коде, вам потребуется NRVO. NRVO сложнее встретиться, так как оно относительно новое. Тем не менее, это доступно. MS Compiler, для одного примера, реализует его с VS2005.

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

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

Тогда как вероятно, что RVO начнет?

Это работа разработчика программного обеспечения, а не компиляторы.

Компиляторы, как правило, оптимизированы, чтобы сделать хороший код хорошо работать хорошо - не плохой.

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

Также обратите внимание, что когда вы говорите:

std::vector<char> GetData() 
{ 
//   :
    return result; 
}

vector<char> x = GetData();

В Калле, result скопируется в «возвращаемое значение», а затем в вызывающем абоненте «возвращаемое значение» копируется в x. Анкет NRVO может избавиться от одной из этих копий, но не оба. Компилятор обязан вызвать копию CTOR хотя бы один раз, потому что он должен предположить, что копия CTT имеет побочные эффекты, которые должны быть выполнены.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top