Usando sonido metálico/libC++:
#include <chrono>
#include <iostream>
#include <vector>
#if SLOW_DOWN
class MyClass
{
void Swap(MyClass &other)
{
std::swap(other.member, member);
}
public:
MyClass()
: member()
{
}
MyClass(const MyClass &other)
: member(other.member)
{
}
MyClass(MyClass &&other)
: member(std::move(other.member))
{
}
MyClass &operator=(MyClass other)
{
other.Swap(*this);
return *this;
}
private:
int member;
};
#else
class MyClass
{
public:
MyClass()
: member()
{
}
private:
int member;
};
#endif
int main()
{
typedef std::chrono::high_resolution_clock Clock;
typedef std::chrono::duration<float, std::milli> ms;
auto t0 = Clock::now();
for (int k = 0; k < 100; ++k)
{
std::vector<MyClass> v;
for (int i = 0; i < 1000000; ++i)
v.push_back(MyClass());
}
auto t1 = Clock::now();
std::cout << ms(t1-t0).count() << " ms\n";
}
$ clang++ -stdlib=libc++ -std=c++11 -O3 -DSLOW_DOWN test.cpp
$ a.out
519.736 ms
$ a.out
517.036 ms
$ a.out
524.443 ms
$ clang++ -stdlib=libc++ -std=c++11 -O3 test.cpp
$ a.out
463.968 ms
$ a.out
458.702 ms
$ a.out
464.441 ms
Esto se parece a aproximadamente un 12% de diferencia de velocidad en esta prueba.
Explicación: Una de estas definiciones tiene un constructor de copia trivial y un operador de asignación de copia. El otro no. "Trivial" tiene un significado real en C++ 11. Significa que la implementación puede usar memcpy
para copiar su clase. O incluso para copiar grandes matrices de tu clase. Entonces, lo mejor es hacer que tus miembros especiales sean triviales si puedes. Eso significa dejar que el compilador los defina. Aunque todavía puede declararlos con = default
si lo prefiere.
Hubo una buena [ASUNTA] (http://stackoverflow.com/questions/9322174/move-assignment-operator-and-if-this-rhs) que tal vez quiera consultar. –
Esta pregunta es demasiado amplia. Debes reducirlo a un escenario específico. Como no hay una receta de cómo escribir el constructor de copia y el operador de asignación de una manera "bien definida" para todas y cada una de las clases. Lo mismo para tu pregunta. –
¿Por qué es demasiado amplio? Hay un patrón generalmente aceptado para el constructor de copias + operador de asignación, ¿por qué no también para el constructor de movimientos? – moswald