ビルトインにBinaryFormatterベースの.NETシリアル化の欠陥は何ですか? (パフォーマンス、柔軟性、制限)組み込みのBinaryFormatterベースの.Netシリアル化の欠点は何ですか?
可能な場合は、いくつかのコードを使用して答えを同行してください。
例:[Serializableを]属性で修飾またはISerializableインターフェイスを実装する必要がありますシリアライズさ
カスタムオブジェクト。
あまり明白な例:
匿名型をシリアル化することはできません。
ビルトインにBinaryFormatterベースの.NETシリアル化の欠陥は何ですか? (パフォーマンス、柔軟性、制限)組み込みのBinaryFormatterベースの.Netシリアル化の欠点は何ですか?
可能な場合は、いくつかのコードを使用して答えを同行してください。
例:[Serializableを]属性で修飾またはISerializableインターフェイスを実装する必要がありますシリアライズさ
カスタムオブジェクト。
あまり明白な例:
匿名型をシリアル化することはできません。
あなたはBinaryFormatter
意味場合:
event
Sを経由して)を期待していなかったものを引き込むの憂鬱な癖を持っていますバッファ "シリアル化API for .NET; protobuf-net
これは:
ISerializable
に差し込む必要があり、WCFは、任意のランダムなオブジェクト、it's very difficult to prove whether it really is serializableを考えます。
シリアル化の難しい問題は、 'Foo'オブジェクトが' Bar'によっても参照されるオブジェクトへの参照を含んでいて、 'Foo'がその参照について' Bar'を求める手段を持たない場合、 'Bar'の言及は、' Foo'の状態の本質的な側面を形作っているかもしれませんが、シリアライザーがそれを知る方法はありません。 – supercat
あなたがシリアライズしているオブジェクトを変更した場合は、シリアル化されてきたし、保存されているすべての古いデータが壊れています。データベースやXMLに保存した場合、古いデータを新しいものに変換する方が簡単です。
これは厳密には変更が破られていることではありません... http://msdn.microsoft.com/en-us/library/system.runtime.serialization.optionalfieldattribute.aspx –
データのバージョン管理は属性によって処理されます。バージョン管理について心配していないなら、これは問題ありません。もしあなたなら、それは大きな問題です。
属性スキームの問題は、多くの簡単なケース(新しいプロパティの追加など)ではかなり滑らかですが、別の新しい列挙型で2つの列挙型の値を置き換えようとするとかなり急速に壊れます(または長寿命永続データに付随する任意の数の一般的なシナリオ)。
問題の詳細を詳しく説明できます。あなたが必要とする場合は、あなた自身のシリアライザを書くことは簡単ですね...
異なるフレームワーク(Say 1.0,1.1,3.5)または異なるCLR間でオブジェクトを前後にシリアル化することはできませんXMLの実装(Mono)は、この目的にはさらに優れています。
または別のバイナリ形式。私の答えを参照してください... –
心に来たもう一つの問題:
クラスは、一般的な実行時フォーマッタとは完全に異なる場所に配置されているのXmlSerializer。また、使用方法は非常に似ていますが、XmlSerializerはIFormatterインターフェイスを実装していません。 BinaryFormatter、XmlSerializer、またはカスタムフォーマッタの間で実行時にシリアル化フォーマッタを入れ替えるだけのコードを追加することはできません。シリアライズされ
XmlSerializerは、ランタイムシリアライザとフォーマッタとはまったく異なる目的を持っています。あなたは交換したくないでしょう。 –
タイプ は[Serializableを] 属性で修飾する必要があります。
あなたはクラスの変数を意味している場合、あなたは間違っています。パブリック変数/プロパティがやや明瞭で1パフォーマンスは、オブジェクトのシリアル化のためにかなり貧弱であるということである自動にシリアライズさ
私は実際に彼がクラスそのものを意味していると思われますが、ISerializableを実装するオプションもあるので、それでも間違っています。たとえそれが正しければ、それはまったく悪いことではないと私は思います。 –
申し訳ありませんが、私はクラス自体がその例を展開することを意味します –
それはAPIに依存します。 BinaryFormatter/SoapFormatterはフィールド(publicまたはprivate)に対して機能します。 XmlSerializerはパブリックメンバー(フィールドまたはプロパティ)に対して機能します。 DataContractSerializerは、[DataMember]とマークされたメンバーに対して(理想的に)機能します。 –
です。私のマシンで10万オブジェクトシリアライズとデシリアライズする
時間:単一のintフィールドを持つオブジェクトをシリアライズこの単純な例では
Time Elapsed 3 ms
Full Serialization Cycle: BinaryFormatter Int[100000]
Time Elapsed 1246 ms
Full Serialization Cycle: BinaryFormatter NumberObject[100000]
Time Elapsed 54 ms
Full Serialization Cycle: Manual NumberObject[100000]
は手でそれを行うよりも20倍遅くかかります。確かに、シリアライズされたストリームにはいくつかの型情報があります。しかし、これは20倍の減速を説明するものではありません。
:オープン文書化標準の.NETのすべてのバージョンに
バイナリファイルを調べると、私はいくつかのことを発見しました。1.タイプとアセンブリのデータは、すべてのタイプについてクリアテキストで書かれています。これは、空間的に非効率的です。 2.すべてのタイプのすべてのオブジェクト/インスタンスには、拡張された型/アセンブリ情報が書き出されています。私たちの手持ちのメカニックでやったことの一つは、知られているタイプのテーブルを書くことでした。書面で型を発見したので、この表の型を調べました。存在しない場合は、型情報とインデックスが割り当てられたエントリが作成されます。次に、型infを整数として渡しました。 (タイプ、データ、タイプ、データ)この「トリック」はサイズを大幅に削減します。これは、データを2回通す必要があるかもしれませんが、オンザフライのプロセスが開発される可能性があります。それは、テーブルに追加するだけでなく、ストリームにプッシュするだけでなく、ストリームからのレスソレーションの注文。
私は、このように最適化するためにコアのシリアライズを再実装したいと考えていましたが、クラスは密封されています!我々はまだそれをジェリーリグにする方法を見つけるかもしれない。
別の状況では、BinaryFormatterで例外がスローされます。
[Serializable]
class SerializeMe
{
public List<Data> _dataList;
public string _name;
}
[Serializable]
class Data
{
public int _t;
}
今日、SerializeMeがシリアル化されるとします。明日、我々はもはやクラスDataが必要なくなり、それを削除することを決定する。したがって、Listを削除するためにSerializeMeクラスを変更します。現在、古いバージョンのSerializeMeオブジェクトを逆シリアル化することは不可能です。
解決策は、余分なクラスを適切に無視するカスタムBinaryFormatterを作成するか、クラスDataを空の定義で保持することです(Listメンバーを保持する必要はありません)。
yerp私はBinaryFormatterに基づくシリアル化を意味していました... –