Устранение ненужных копий при построении составных объектов - PullRequest
2 голосов
/ 02 мая 2011

Я думал о разработке некоторого именованного кода параметра, но это заставило меня задуматься о некотором коде, подобном следующему:

#include <utility>

int main() 
{
  using std::make_pair;
  auto x = make_pair(1, make_pair(2, make_pair(3, make_pair(4,5))));
}

Теперь наивная реализация этого подойдет "make_pair (4,5)«сначала скопируйте результат во второй элемент« make_pair (3, ...) », а затем скопируйте его во второй элемент« make_pair (2, ...) »и т. д.

Это приведет к производительности O (n ^ 2), к сожалению, с большим количеством ненужных копий.Я не могу понять, как (именованная) оптимизация возвращаемого значения также помогает здесь.

В идеале, make_pair(4,5) понимает, что это будет в последнем месте x, и создает себяв этом месте.

Далее:

#include <utility>

int main() 
{
  using std::make_pair;
  auto&& x1 = make_pair(3, make_pair(4,5));
  auto x2 = make_pair(1, make_pair(2, std::move(x1)));
}

Я бы хотел избежать копий в коде, подобном этому.

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

Ответы [ 2 ]

5 голосов
/ 02 мая 2011

[N] RVO помогает в таких случаях.По сути, происходит то, что один составной объект выделяется, и «возвращаемое значение» от каждой из функций в конечном итоге попадает непосредственно в объект, который будет содержать результат.

Если вы собираетесь делать большую частьэто (особенно в C ++ 11), почти наверняка проще, проще и прямее использовать кортеж, поэтому ваш:

auto x = make_pair(1, make_pair(2, make_pair(3, make_pair(4,5))));

будет выглядеть как:

auto x = make_tuple(1, 2, 3, 4, 5);

Это, вероятно, не сильно повлияет на сгенерированный код, но (по крайней мере, IMO) его намного легче читать.

1 голос
/ 02 мая 2011
make_pair(1, make_pair(2, make_pair(3, make_pair(4,5))));

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

Я думаю, что вы действительно хотите make_tuple .

...