データ オブジェクトの比較を実行して、オブジェクトの 1 つのバージョンが別のバージョンと異なるかどうかを判断するアプリケーションがあります。私たちのアプリケーションは、これらのオブジェクトの大規模なキャッシュも行いますが、これらの比較を行う際にパフォーマンスの問題が発生しました。
ワークフローは次のとおりです。
- データ項目 1 は、メモリ内の現在の項目です。このアイテムは最初にキャッシュから取得され、ディープ クローンが作成されました (辞書などのすべてのサブ オブジェクト)。次に、データ項目 1 が編集され、そのプロパティが変更されます。
- 次に、このオブジェクトをキャッシュに保存された元のバージョンと比較します。データ項目 1 が複製され、そのプロパティが変更されたため、これらのオブジェクトは異なるはずです。
ここにはいくつかの問題があります。
主な問題は、ディープ クローン メソッドが非常にコストがかかることです。浅いクローンに対してプロファイリングしたところ、10 倍遅くなりました。それはがらくたです。ディープクローンを作成する方法は次のとおりです。
public object Clone()
{
using (var memStream = new MemoryStream())
{
var binaryFormatter = new BinaryFormatter(null, new StreamingContext(StreamingContextStates.Clone));
binaryFormatter.Serialize(memStream, this);
memStream.Seek(0, SeekOrigin.Begin);
return binaryFormatter.Deserialize(memStream);
}
}
最初は以下を使用してクローンを作成していました。
public object Clone()
{
return this.MemberwiseClone();
}
これはパフォーマンスが向上しましたが、浅い複製を行うため、辞書など、このオブジェクトのプロパティであったすべての複雑なオブジェクトは複製されませんでした。オブジェクトには、キャッシュ内にあったオブジェクトと同じ参照が含まれているため、比較するとプロパティは同じになります。
では、オブジェクト グラフ全体のクローン作成をカバーする C# オブジェクトのディープ クローン作成を効率的に行う方法はありますか?