1. ホーム
  2. c++

[解決済み] C++のスマートポインタのオーバーヘッドは通常のポインタと比較してどの程度ですか?

2022-06-06 06:56:06

質問

C++11 のスマート ポインターは、通常のポインターと比較してどの程度のオーバーヘッドがありますか。言い換えると、スマート ポインターを使用した場合、私のコードは遅くなるのでしょうか、また、遅くなる場合はどのくらい遅くなるのでしょうか。

具体的には、私は C++11 の std::shared_ptrstd::unique_ptr .

スマート ポインターはその内部状態 (参照カウントなど) も保存する必要があるため、スタックに押し込まれるものが大きくなるのは明らかですが (少なくとも私はそう思います)、問題は、これがパフォーマンスにどの程度影響するのか (まったく影響しないとしたら) です。

たとえば、私は関数から通常のポインタの代わりにスマートポインタを返します。

std::shared_ptr<const Value> getValue();
// versus
const Value *getValue();

例えば、ある関数が通常のポインタの代わりにスマートポインタをパラメータとして受け取る場合です。

void setValue(std::shared_ptr<const Value> val);
// versus
void setValue(const Value *val);

どのように解決するのですか?

std::unique_ptr は、自明でないデレタと一緒に提供した場合のみ、 メモリのオーバーヘッドを持ちます。

std::shared_ptr は常に参照カウンタのためのメモリオーバーヘッドを持ちますが、それは非常に小さいものです。

std::unique_ptr はコンストラクタ中(提供されたデレタをコピーしたり、ポインタをヌル初期化する必要がある場合)とデストラクタ中(所有するオブジェクトを破壊する)のみ時間のオーバーヘッドを持ちます。

std::shared_ptr は、コンストラクタ(参照カウンタを作成する)、デストラクタ(参照カウンタをデクリメントし、場合によってはオブジェクトを破壊する)、および代入演算子(参照カウンタをインクリメントする)において時間オーバーヘッドを持っています。スレッドセーフを保証するために std::shared_ptr のスレッドセーフ保証により、これらのインクリメント/デクリメントはアトミックであり、したがって、いくつかのより多くのオーバーヘッドを追加します。

デリファレンス(所有するオブジェクトへの参照を取得すること)の時間的オーバーヘッドは、どれもないことに注意してください。

まとめると、多少のオーバーヘッドはありますが、スマートポインタの作成と破棄を継続的に行わない限り、コードが遅くなることはないはずです。