移動セマンティクスをテストしようとして、メモリを割り当てる単純なクラスを構築します。
class CTest
{
private:
std::size_t size;
char* buffer;
public:
CTest(std::size_t size) : size(size), buffer(nullptr)
{
buffer = new char[size];
}
~CTest()
{
delete[] buffer;
}
CTest(const CTest& other) : size(other.size), buffer(nullptr)
{
buffer = new char[size];
}
CTest(CTest&& other) : size(other.size), buffer(other.buffer)
{
other.buffer = nullptr;
}
};
ご覧のとおり、参照によってコピーすると新しいメモリが割り当てられる非常に単純なクラスです(テストのためだけに、その内容をコピーしません)。移動コンストラクターは、引数データを指す内部ポインターを作成するだけで、新しいメモリは割り当てられません。
次のようなヘルパー関数で Windows QueryPerformanceCounter() を使用して im をベンチマークする場合:
template <typename Func>
__int64 Benchmark(Func f, size_t count)
{
LARGE_INTEGER li = {};
QueryPerformanceCounter(&li);
__int64 start = li.QuadPart;
f(count);
QueryPerformanceCounter(&li);
return li.QuadPart - start;
}
非常に単純なベンチマーク関数で、開始時間を保存し、終了時間から減算して結果を返します。テスト機能については次のとおりです。
void Alloc_Ref(size_t count)
{
CTest t(1024);
for(size_t i = 0; i < count; ++i)
CTest c(t);
}
void Alloc_Move(size_t count)
{
for(size_t i = 0; i < count; ++i)
CTest c(CTest(1024));
}
Alloc_Ref は事前に初期化された変数を使用するため、コピー コンストラクターを呼び出します。Alloc_Move は単に一時クラスを使用するため、移動コンストラクターを呼び出します。
次のようにテストを呼び出しています:
cout << "Ref: " << Benchmark(Alloc_Ref, 1000000) << " ms." << endl;
cout << "Move: " << Benchmark(Alloc_Move, 1000000) << " ms." << endl;
問題は、Alloc_Move が移動コンストラクターを呼び出しておらず、引き続きコピー コンストラクターを呼び出していることです。不足しているものはありますか?
同様に重要なのは、Alloc_Move でこれを行う場合です。CTest c(move(CTest(1024))
移動コンストラクターを呼び出しますが、Alloc_Ref コンストラクターよりも遅いですが、何か不足していますか?
長い投稿で申し訳ありませんが、よろしくお願いします。