unique_ptr はコピー不可で移動セマンティクスがあるため、ほとんどの状況で shared_ptr よりも unique_ptr が好まれるとよく読みます。shared_ptr は、コピーと参照カウントによるオーバーヘッドを追加します。
しかし、いくつかの状況でunique_ptrをテストすると、対応するものよりも(アクセスが)著しく遅いようです
たとえば、gcc 4.5では次のようになります。
edit : print メソッドは実際には何も印刷しません
#include <iostream>
#include <string>
#include <memory>
#include <chrono>
#include <vector>
class Print{
public:
void print(){}
};
void test()
{
typedef vector<shared_ptr<Print>> sh_vec;
typedef vector<unique_ptr<Print>> u_vec;
sh_vec shvec;
u_vec uvec;
//can't use initializer_list with unique_ptr
for (int var = 0; var < 100; ++var) {
shared_ptr<Print> p(new Print());
shvec.push_back(p);
unique_ptr<Print> p1(new Print());
uvec.push_back(move(p1));
}
//-------------test shared_ptr-------------------------
auto time_sh_1 = std::chrono::system_clock::now();
for (auto var = 0; var < 1000; ++var)
{
for(auto it = shvec.begin(), end = shvec.end(); it!= end; ++it)
{
(*it)->print();
}
}
auto time_sh_2 = std::chrono::system_clock::now();
cout <<"test shared_ptr : "<< (time_sh_2 - time_sh_1).count() << " microseconds." << endl;
//-------------test unique_ptr-------------------------
auto time_u_1 = std::chrono::system_clock::now();
for (auto var = 0; var < 1000; ++var)
{
for(auto it = uvec.begin(), end = uvec.end(); it!= end; ++it)
{
(*it)->print();
}
}
auto time_u_2 = std::chrono::system_clock::now();
cout <<"test unique_ptr : "<< (time_u_2 - time_u_1).count() << " microseconds." << endl;
}
平均して (g++ -O0) を取得します。
- shared_ptr : 1480 マイクロ秒
- unique_ptr : 3350 マイクロ秒
違いはどこから来るのですか?それは説明可能ですか?