Programmer
Programmer

Reputation: 8727

What is the fastest way to swap two complex structures?

I need to swap the value of one structure with another and believe that swap will be faster than copy - am I correct?

#include <iostream>
#include <algorithm>
#include <vector>

class B
{
 public:
  int y;
  std::vector<int> z;
  B(){std::cout << "Called" << std::endl;}
 private:
 int z1;
};

int main()
{
 B b1, b2;
 b1.z.push_back(1);
 std::swap(b1,b2);
 std::cout << b2.z[0] << std::endl;
 b1.z.push_back(1);
 b2 = std::move(b1);
 std::cout << b2.z[0] << std::endl;
 b1.z.push_back(1);
 std::exchange(b1, b2);
 std::cout << b2.z[0] << std::endl;
 b1.z.push_back(1);
 b2 = std::forward<B>(b1);
 std::cout << b2.z[0] << std::endl;
}

The above code does the swaps as expected but I am not sure which is the fastest way. My objective is to copy values (swap if it is faster) of one structure variable to another. In the real code the structure will have complex user defined types.

I understand that similarly there will ways to copy - but which way is the best / safe / fast to copy to destination?

Do I need to take care of some operator / constructor to aid it?

Upvotes: 1

Views: 567

Answers (2)

NathanOliver
NathanOliver

Reputation: 180965

I understand that similarly there will ways to copy - but which way is the best / safe / fast to copy to destination?

std::swap actually won't copy as long as your type is movable. In its simplest form it looks like

template<typename T>
void swap(T& lhs, T& rhs)
{
    T tmp{std::move(rhs)};
    rhs = std::move(lhs);
    lhs = std::move(tmp);
}

So, as long as it is faster to move your object then it is to copy it, then swapping will be faster. If not, then they will have the same performance.

Upvotes: 1

Bathsheba
Bathsheba

Reputation: 234835

Given

  1. The compiler is allowed to generate a move constructor for B (research the rule of 5), which is a memberwise move construction subject to the as-if rule

  2. std::move uses the move constructor if available

  3. std::swap uses std::move

  4. std::vector has a move constructor

, using simply

std::swap(b1, b2);

will be very hard to beat.

Upvotes: 2

Related Questions