Использование 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
Это похоже на разницу скорости примерно в 12% в этом тесте.
Объяснение: В одном из этих определений есть тривиальный конструктор копирования и оператор назначения копирования,Другой нет.«Тривиальный» имеет реальное значение в C ++ 11.Это означает, что реализация может использовать memcpy
для копирования вашего класса.Или даже скопировать большие массивы вашего класса.Поэтому лучше, если можете, сделать своих специальных членов тривиальными.Это значит позволить компилятору определить их.Хотя вы все равно можете объявить их с = default
, если хотите.