Korzystanie clang/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
To wygląda jak około 12% różnicy prędkości na tym teście.
Objaśnienie: Jedna z tych definicji ma trywialny konstruktor kopiowania i operator przypisania kopiowania. Drugi nie. "Trivial" ma prawdziwe znaczenie w C++ 11. Oznacza to, że implementacja może używać klasy memcpy
do kopiowania. Lub nawet skopiować duże tablice twojej klasy. Więc najlepiej jest sprawić, by twoi wyjątkowi członkowie byli banalni, jeśli możesz. Oznacza to, że pozwala to kompilatorowi je zdefiniować. Chociaż nadal możesz je zadeklarować pod numerem = default
, jeśli wolisz.
Było dobre [pytanie SO] (http://stackoverflow.com/questions/9322174/move-assignment-operator- i-if-this-rhs), na które warto spojrzeć. –
To pytanie jest zbyt szerokie. Musisz oderwać go do określonego scenariusza. Ponieważ nie ma przepisu, w jaki sposób napisać konstruktor kopiowania i operator przypisania w "dobrze określony" sposób dla każdej klasy. To samo dotyczy twojego pytania. –
Dlaczego jest zbyt szeroki? Istnieje ogólnie przyjęty wzorzec dla konstruktora kopiowania i operatora przypisania, dlaczego nie dla konstruktora ruchu? – moswald