3

以下のコードを使用して、カスタム オブジェクトのシリアライズとデシリアライズを試みました。

[Serializable]
public class TaskProperty
{
    public int Id { get; set; }
    public DateTime ScheduleTime { get; set; }
    public TimeSpan InitializationTime { get; set; }
    public Nullable<DateTime> InstantOfStart { get; set; }
    public TimeSpan TotalElapsedTime { get; set; }
}

// Main
var serializer = new DataContractSerializer(typeof(TaskProperty));
var reader = new FileStream("myfile.xml", FileMode.Open);
TaskProperty deserialized = (TaskProperty)(serializer.ReadObject(reader));
reader.Close();
Console.WriteLine("deserialized: {0}", deserialized);

TaskPropertyクラスがDataContract属性 (および各プロパティの属性) で装飾されている場合、逆シリアル化は、属性DataMemberで装飾されている場合よりもはるかに高速です。Serializable

  • DataContractおよび属性を使用するとDataMember、逆シリアル化はほぼ即時に行われます。
  • 属性を使用Serializableすると、逆シリアル化は非常に遅くなります (約 30 秒かかります)。

なんで?

更新...さらに、逆シリアル化の前に同じ型のオブジェクト (明らかに内容が異なる) のシリアル化がある場合、逆シリアル化は高速ですが、シリアル化は低速です。同様に、シリアル化の前に同じ型のオブジェクトを逆シリアル化すると、逆シリアル化は遅くなりますが、シリアル化は高速です。

更新 2...完全を期すために、シリアル化および逆シリアル化する必要があるカスタム クラスを追加しました。

UPDATE 3...まあ、属性に影響する遅さの原因を発見したのかもしれませんが、そのSerializable理由はわかりません。基本的に、5 つのプロパティに関連する 5 つのプライベート フィールドを明示的に宣言すると、結果として、最初のシリアル化 (または逆シリアル化) はほぼ瞬時に行われます。なんで?

4

3 に答える 3

1

おそらくデバッグ モードでテストしており、代わりにシリアライザーが適切に NGEN 化されたリリース モードでテストする必要があります。

編集:「最初のシリアル化だけが遅いため、平均パフォーマンスが向上します」という上記のコメントについて。NGEN が原因ではないという私の疑いをほぼ裏付けています。プロジェクト プロパティ < ビルド < シリアライゼーション アセンブリの生成で、プロジェクトのビルド設定を確認する必要があります。

リリース ビルドに対して無効になっていないことを確認したい (必要に応じて、デバッグに対しても有効にすることができます)

いくつかの詳細情報を見つけることができます:

XmlSerializer の起動時に 64 ビット システムでパフォーマンスが大幅に低下する

http://blogs.msdn.com/b/billwert/archive/2008/02/23/use-of-sgen-exe-to-avoid-common-xmlserializer-performance-pitfalls.aspx

于 2012-09-07T15:38:46.873 に答える
1

100% 確信はありませんが、私の推測では次のようになります。

1) .NET はアセンブリのメタデータに属性情報を埋め込むため、データ コントラクト シリアライザーは、クラスのすべてのデータ メンバー属性を見つけるためにリフレクションを行う必要はありません。

2) [Serializable] を使用すると、シリアライザーはオブジェクトのすべてのフィールドを検査し、コストがかかるリフレクションを使用してこれを行う必要があります。

于 2012-09-07T11:17:47.477 に答える
1

最初の呼び出し後のシリアル化の高速化に関する更新についてコメントするだけです。

おそらく、シリアライザーはリフレクションを使用してメタデータを構築し、おそらく動的メソッドを使用して、その型を初めて処理する必要があるときに、その型のシリアル化を実行します。

私がジェネリックシリアライザーを書いていたら、それが私がすることです。すべてのプロパティを反映し、動的メソッドを ILEmit して実際のシリアル化を実行し、生成されたメソッドを保存して、同じ型が再びシリアル化または逆シリアル化されるたびに使用します。

于 2012-09-07T15:33:48.307 に答える