5

オブジェクトのクローンを作成するコードを最適化しようとしています:

#region ICloneable
public object Clone()
{
    MemoryStream buffer = new MemoryStream();
    BinaryFormatter formatter = new BinaryFormatter();

    formatter.Serialize(buffer, this);     // takes 3.2 seconds
    buffer.Position = 0;
    return formatter.Deserialize(buffer);  // takes 2.1 seconds
}
#endregion

かなり標準的なもの。問題は、オブジェクトがかなり頑丈で、5.4 秒かかることです (ANTS プロファイラーによると、プロファイラーのオーバーヘッドがあると確信していますが、それでも)。

クローンを作成するためのより優れた高速な方法はありますか?

4

5 に答える 5

7
  1. ICloneable を実装しないでください。

  2. オブジェクトを複製する簡単な方法は、同じタイプの新しいインスタンスを作成し、元のインスタンスから新しいインスタンスにすべてのフィールドをコピー/複製することです。任意のクラスの任意のオブジェクトを複製できる「一般的な」複製メソッドを考え出そうとしないでください。

例:

class Person
{
    private string firstname;
    private string lastname;
    private int age;

    public Person(string firstname, string lastname, int age)
    {
        this.firstname = firstname;
        this.lastname = lastname;
        this.age = age;
    }

    public Person Clone()
    {
        return new Person(this.firstname, this.lastname, this.age);
    }
}
于 2010-05-06T22:36:18.577 に答える
2

回答: クローンを作成するためのより良い方法があります。

リフレクションまたは式ツリーは、シリアル化よりもはるかに高速です (リフレクションは5 倍速く、式ツリーは20 倍速くなります)。

ここに画像の説明を入力

このリンクされたクローニング関数を拡張メソッドとして使用すると、各クローニング コードは次のように縮小されます。

#region ICloneable
public object Clone()
{
    return this.DeepCopyByExpressionTree();
}
#endregion

拡張メソッドを使用するには、ソリューションの任意の場所にファイルDeepCopyByExptressionTrees.csがあれば十分です。

于 2016-08-03T07:10:39.213 に答える
1

私が理解しているように、ストリームは、このような内部のものでさえも高価です。
新しいオブジェクトを作成し、関連するフィールドを更新してオブジェクトを同じ状態にしようとしましたか? あなたの方法の方が時間がかからないとは信じがたいです。

于 2010-05-06T22:37:42.457 に答える
1

これは、クローンを作成するためのかなり高価な方法です。オブジェクトがネットワークに接続されることはないため、シリアライゼーションを行う時間は基本的に無駄です。メンバーごとのクローンを作成する方がはるかに高速です。私はそれが自動魔法の解決策ではないことを理解していますが、それは最速です.

これらの行に沿ったもの:

class SuperDuperClassWithLotsAndLotsOfProperties {
  object Clone() {
    return new SuperDuperClassWithLotsAndLotsOfProperties {
      Property1 = Property1,
      Property2 = Property2,
    }

  public string Property1 {get;set;}
  public string Property2 {get;set;}
  }
}
于 2010-05-06T22:38:05.493 に答える