0

私のコードでは、COM インターフェイスを介して従来の Delphi オブジェクトをインスタンス化しています。このクラスは何度もインスタンス化する必要があるため、インスタンス化のオーバーヘッドを下げるために、すべての呼び出しの 70% が共通の結果オブジェクトを持つポイントでキャッシュします。

ただし、キャッシュ後にオブジェクトを変更すると、変更もキャッシュに保持されます。これは、COM ラッパー インスタンスが値ではなく参照によって渡されていると思わせます。
キャッシュ内のオブジェクトが参照ではなく値で渡されるようにするにはどうすればよいですか?

4

2 に答える 2

0

まず、これは必要ですか?

私は「すべてのパフォーマンスの問題を解決する測定」の支持者ではありませんが、あなたの場合はそうすべきです。

COM オブジェクトをインスタンス化するオーバーヘッド (最初の呼び出しのペナルティの後) は非常に低いです。15 年前のコンピューターで多くの小さなオブジェクトを使用できるように設計されていたことを思い出してください。.NET のオーバーヘッドはそれほど大きくないと思います。そのため、問題はオブジェクト自体の初期化です。

タイトなループで 1000 個のオブジェクトをインスタンス化することで簡単に確認できます (最初の呼び出しを破棄します。非常にコストがかかる可能性があり、平均を損なう可能性があります)。

COM オブジェクトは本質的に参照
渡しです COM オブジェクトの基本的なインターフェイスはインスタンスへの参照カウント ポインターであり、COM は汎用の "Clone" メソッドを公開しないため、COM オブジェクトには "値渡し" はありません。

考えられる解決策: コピー オン ライト
インスタンス化が非常に高価であり、大部分の呼び出しが既定のインスタンスを介して実行できる場合は、コピー オン ライト スキームを実装できます。

デフォルト インスタンスへの参照と、0 に初期化されたプライベート インスタンスへの参照を保持するラッパー クラスを作成する必要があります。

プライベート インスタンスが である限りnull、すべての getter 関数はデフォルト インスタンスに転送されます。それ以外の場合は、プライベート インスタンスに転送されます。

すべてのセッター/ミューテーター呼び出しはプライベート インスタンスに転送され、存在しない場合は作成されます。

これにより、プライベート インスタンスの作成が最初の変更呼び出しまで遅延します。ただし、このコンポーネントの対象となるすべてのインターフェイス全体をラップする必要があります。

于 2010-01-07T11:23:37.533 に答える
0

可能であれば、オブジェクトのコピーを明示的に複製してから、そのコピーをキャッシュする必要があると思います。たとえば、C# の Cloning objectsMemberwiseCloneへの回答で言及されているメソッドなどを参照してください。

于 2010-01-07T11:04:34.603 に答える