参照ではなく値によってキャッシュするための .net COM ラッパーの追加
-
19-09-2019 - |
質問
私のコードでは、COM インターフェイスを介して従来の Delphi オブジェクトをインスタンス化しています。このクラスは何度もインスタンス化する必要があるため、インスタンス化のオーバーヘッドを減らすために、すべての呼び出しの 70% が共通の結果オブジェクトを持つ時点でクラスをキャッシュします。
ただし、キャッシュされた後にオブジェクトを変更すると、変更はキャッシュにも保持されます。これにより、COM ラッパー インスタンスが値ではなく参照によって渡されているように思えます。
キャッシュ内のオブジェクトが参照ではなく値によって渡されるようにするにはどうすればよいですか?
他のヒント
まず、これは必要ですか?
私は「パフォーマンスの問題はすべて測定で解決する」ことを支持しませんが、あなたの場合はそうすべきです。
(最初の呼び出しペナルティの後) COM オブジェクトをインスタンス化するオーバーヘッド自体は非常に低いです。15 年前のコンピューター上で多くの小さなオブジェクトを処理できるように設計されていたことを思い出してください。.NET のオーバーヘッドはそれ以上ではないと思います。したがって、問題はオブジェクト自体の初期化です。
タイトなループで 1000 個のオブジェクトをインスタンス化することで、それを簡単に確認できます (最初の呼び出しは破棄します。非常にコストがかかるため、平均値が損なわれる可能性があります)。
COM オブジェクトは本質的に参照によるものです
COM オブジェクトの基本インターフェイスは参照カウントされたインスタンスへのポインタであり、COM は汎用の "Clone" メソッドを公開しないため、COM オブジェクトには "値渡し" はありません。
考えられる解決策:コピーオンライト
Only if インスタンス化の場合 本当に 高価であり、呼び出しの大部分はデフォルトのインスタンスを通じて実行できるため、コピーオンライト スキームを実装できます。
デフォルトのインスタンスへの参照と、0 に初期化されたプライベート インスタンスへの参照を保持するラッパー クラスを作成する必要があります。
プライベート インスタンスがある限り、 null
, 、すべてのゲッター関数はデフォルトのインスタンスに転送され、それ以外の場合はプライベート インスタンスに転送されます。
すべてのセッター/ミューテーター呼び出しはプライベート インスタンスに転送され、プライベート インスタンスが存在しない場合は作成されます。
これにより、プライベート インスタンスの作成が最初の変更呼び出しまで遅延します。ただし、このコンポーネントの対象となるすべてのインターフェイス全体をラップする必要があります。