この素敵なコピー オン ライト ポインターの実装を見たところです。それは非常に一般的で便利に見えるので、私の質問は次のとおりです。そのようなクラスは C++ ツールキット (boost、loki など) のいずれかに含まれていますか? そうでない場合、それは本当に便利なイディオムであり、明らかに一般的な実装が実行可能であるように見えるため、その理由を本当に知りたいです(私がリンクしたもののように)。
3 に答える
auto_ptr
その可能性については多くの議論があり、参照カウント COW ポインターの場合と同様に、最終的に出てきたものの少なくとも 1 つの提案されたバージョンがありました。
残念ながら、COW の時期はほとんど過ぎています。COW ポインター (または COW 何でも) をスレッドセーフにすると、重大なパフォーマンスの問題が発生する可能性があります。
編集:それを読み直して、COWのすべての使用が必ずしも時代遅れであるとは限らないことを指摘する義務があると感じています. それでも意味が通じる時があります。スレッド セーフなインクリメントのオーバーヘッドはほぼ固定されています。したがって、COW が意味をなすためには、オブジェクトがどれだけ大きくなければならないか、またはコピーにどれだけのコストがかかるかだけの問題です。また、(変更されていない) オブジェクトのコピーが多数ある場合や場所もあり、メモリの節約は合理的なトレードオフになる可能性があります。メモリの節約は、余分なプロセッサ時間を正当化します。ページングの小さなデータをディスクに保存したり、ディスクから保存したりできる場合は、急いで先に進むことができます。
Jerry Coffinが言ったように、COWイディオムがパフォーマンスの問題を引き起こしたことが実証されています...しかし実際には別の問題があります。
(リンク先の記事に示されているように)実際にCOWの一般的な実装を作成することはできません。COWではstd::string
、文字列の状態を実際に変更する操作が呼び出されるたびに、コピーの実装が実行されます。しかし、ポインタはどのようにしてそれを知ることになっていますか?それが指しているクラスについての知識はありません。
たとえば、私がこれを行うと仮定しましょう:
void method(Foo& foo, flag_t flag)
{
if (flag == flag::Yes) foo.modify();
}
void invoke(COWPointer<Foo> ptr)
{
method(*ptr, flag::No);
}
おっと!Foo
オブジェクトは変更されませんが、コピーを作成します。
問題は、このCOWクラスは役に立ちますが、実際にはそれをラップする必要があるということです。
class Foo
{
public:
private:
COWPointer<FooImpl> mImpl;
};
そして、オブジェクトを実際に変更するFooのメソッドは、FooImpl
状態のコピーを担当します。確かにクラスは役に立ちますが、それも特効薬ではありません。
そして、このすべての問題... MTアプリケーションの同期の問題のために、実際にパフォーマンスが向上するかどうかはわかりません...
パフォーマンスの問題をすでに処理しているユーザーにペナルティを課す状況でクラスを微調整してゲインを上げるよりも、可能な限り(参照/ポインターを使用して)コピーを実際に回避する方が簡単ではありませんか?
「ポインター」と「書き込み時のコピー」の間には矛盾があります。定義上、ポインターを逆参照してもポインターは変更されず、変更しても変更され*p
ませんp
。
そのため、const ポインターを逆参照することができ、結果の左辺値を変更可能にすることができます。
あなたは本当にポインタではなく、1要素のコンテナについて話しているのです。