3

データ オブジェクトの比較を実行して、オブジェクトの 1 つのバージョンが別のバージョンと異なるかどうかを判断するアプリケーションがあります。私たちのアプリケーションは、これらのオブジェクトの大規模なキャッシュも行いますが、これらの比較を行う際にパフォーマンスの問題が発生しました。

ワークフローは次のとおりです。

  1. データ項目 1 は、メモリ内の現在の項目です。このアイテムは最初にキャッシュから取得され、ディープ クローンが作成されました (辞書などのすべてのサブ オブジェクト)。次に、データ項目 1 が編集され、そのプロパティが変更されます。
  2. 次に、このオブジェクトをキャッシュに保存された元のバージョンと比較します。データ項目 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# オブジェクトのディープ クローン作成を効率的に行う方法はありますか?

4

4 に答える 4

6

クローンを作成する必要があるすべてのデータ オブジェクトに ICloneable を明示的に実装しないと、ジェネリック バイナリ シリアル化よりもはるかに優れたものになることはありません。別の可能なルートはリフレクションですが、パフォーマンスを探している場合は、これでも満足できません。

ディープ コピーの場合は ICloneable を、オブジェクトが異なる場合は比較する場合は IComparable を使用してヒットすることを検討します...パフォーマンスがそれほど大きな問題である場合。

于 2009-04-28T22:29:23.157 に答える
1

多分あなたは深いクローンを作るべきではありませんか?

その他のオプション:

1)「キャッシュされた」オブジェクトに元の状態を記憶させ、何かが変更されるたびに「変更済み」フラグを更新します

2) 元の状態を覚えておらず、何かが変更されたら、オブジェクトにダーティとしてフラグを立てるだけです。次に、元のソースからオブジェクトをリロードして比較します。オブジェクトが変更される頻度は、変更されないよりも少なく、同じ値に戻る頻度もさらに低いに違いありません。

于 2009-04-28T22:20:20.213 に答える
1

あなたの制限や要件が何であるかがわからないため、私の回答があなたのケースに当てはまらない可能性がありますが、一般的な目的のクローン作成には問題があると思います. すでに遭遇したように、パフォーマンスが問題になる場合があります。オブジェクト グラフ内の一意のインスタンスを識別し、正確なコピーを作成する必要があります。これは、バイナリ シリアライザーが行うことですが、それ以上のことも行います (シリアライゼーション自体)。あなたが期待していたよりも遅いことを見て、私は驚かない. 私も同様の経験があります(ちなみにキャッシングにも関連しています)。私のアプローチは、クローン作成を自分で実装することです。つまり、実際に複製する必要があるクラスに IClonnable を実装します。アプリケーションにキャッシュしているクラスはいくつありますか? 多すぎる場合 (手動でクローニングをコーディングするには)、

于 2009-04-28T22:29:29.800 に答える