1

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?

StoryTeller - Unslander Monica
  • 165,132
  • 21
  • 377
  • 458
Programmer
  • 8,303
  • 23
  • 78
  • 162
  • On modern CPUS, unless the vector class member contains many values, the relative performance will depend more on the cosmic rays in the vicinity, than anything else. – Sam Varshavchik Feb 26 '19 at 13:33
  • 1
    You only need to implement copy and swap functionality yourself if your object manages a ressource (pointer, network connection, ...) by itself, which is not the case in your example. Which one is the fastest: I guess you have to benchmark this for your specific case, especially since you say that the real code uses "complex user defined types" that we don't know. [Here](https://stackoverflow.com/questions/3279543/what-is-the-copy-and-swap-idiom) you can find info on copy and swap functionallity including the move constructor that is available since C++11. – AlbertM Feb 26 '19 at 13:35
  • 2
    You should check out the documentation for std::exchange, it moves the value of b2 into b1 and returns the old value of b1, thus using b2 after std::exchange(b1, b2) is undefined behavior. – Jakub Jůza Feb 26 '19 at 13:38
  • User Defined Types are classes that have huge data structure – Programmer Feb 26 '19 at 13:38

2 Answers2

2

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.

Bathsheba
  • 231,907
  • 34
  • 361
  • 483
1

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.

Toby Speight
  • 27,591
  • 48
  • 66
  • 103
NathanOliver
  • 171,901
  • 28
  • 288
  • 402