Is specializing std::swap deprecated now that we have move semantics?

fredoverflow picture fredoverflow · Dec 23, 2011 · Viewed 16.6k times · Source

Possible Duplicate:
Move semantics == custom swap function obsolete?

This is how std::swap looks like in C++11:

template<typename T>
void swap(T& x, T& y)
{
  T z = std::move(x);
    x = std::move(y);
    y = std::move(z);
}

Do I still have to specialize std::swap for my own types, or will std::swap be as efficient as it gets, provided that my class defines a move constructor and a move assignment operator, of course?

Answer

Howard Hinnant picture Howard Hinnant · Dec 23, 2011

The specialization of std::swap is now optional, but not deprecated. The rationale is performance.

For prototyping code, and perhaps even for much shipping code, std::swap will be plenty fast. However if you're in a situation where you need to eek out every little bit from your code, writing a custom swap can still be a significant performance advantage.

Consider the case where your class essentially has one owning pointer and your move constructor and move assignment just have to deal with that one pointer. Count machine loads and stores for each member:

Move constructor: 1 load and 2 stores.

Move assignment: 2 loads and 2 stores.

Custom swap: 2 loads and 2 stores.

std::swap is 1 move construction and 2 move assignments, or: 5 loads and 6 stores.

A custom swap is potentially still two or three times faster than std::swap. Though any time you're trying to figure out the speed of something by counting loads and stores, both are going to be wicked fast.

Note: In computing the cost of your move assignment, be sure and take into account that you will be moving into a moved-from value (in the std::swap algorithm). This often negates the cost of a deallocation, though at the cost of a branch.