3

何百万ものフロートを取り、データベースに 5,000 個のバッチでバイナリとして格納するタスクがあります。これにより、シリアライゼーションのパフォーマンスについて興味深いことを学ばざるを得なくなりました。

驚いたことの 1 つは、シリアライズされたデータのサイズです。これは、予想を 10 倍上回っています。このテストでは、4 バイトの float が 55 バイトにシリアル化され、8 バイトの double が 59 バイトにシリアル化されていることがわかります。

ここで何が起きてるの?float 値を単純に 4 バイトに分割するだけだと思っていました。残りの 51 バイトは何ですか?

private void SerializeFloat()
{
    Random rnd = new Random();
    IFormatter iFormatter = new BinaryFormatter();

    using (MemoryStream memoryStream = new MemoryStream(10000000))
    {
        memoryStream.Capacity = 0;
        iFormatter.Serialize(memoryStream, (Single)rnd.NextDouble());
        iFormatter.Serialize(memoryStream, rnd.NextDouble());
    }
}
4

4 に答える 4

5

シリアル化は、単にビットとバイトをストリームにブリッティングするだけではありません。シリアライゼーションは構造化された出力です。この構造は、実際の違いを説明しています。フレームワークは、シリアル化されたデータ内のオブジェクトのタイプと数など、さまざまな可能性を知らせる追加情報をエンコードします。実装の詳細はそのままにしておくのが最善です。

構造化されていない出力が必要な場合は、代わりにを使用できますBinaryWriter

于 2013-05-22T18:04:27.260 に答える
3

バイナリ シリアル化はタイプ セーフです。データを逆シリアル化すると、まったく同じオブジェクトが返されます。

これを機能させるために、BinaryFormatter は、シリアル化するオブジェクトの型に関する追加データを追加します。余分なオーバーヘッドが発生しています。FileStream にシリアル化し、生成されたファイルを 16 進ビューアーで見ることで確認できます。タイプ名の「System.Single」や、値が格納されるフィールドの名前の「m_value」などの文字列が表示されます。オーバーヘッドを削減する良い方法は、代わりに配列をシリアル化することです。

BinaryWriter は正反対で、非常にコンパクトですが、タイプ セーフではありません。その間にはたくさんの選択肢があります。

于 2013-05-22T18:29:51.103 に答える
1

.NET シリアライゼーションでは、実際の 8 バイト以外の情報double(型情報など) が大量にスローされます。ファイルを使用して、またはクラスStreamによって取得されたバイトを書き込むことができます。byte[] BitConverter.GetBytes(double)BinaryWriter

.NET シリアライゼーションには多くの代替手段があります。

  • テキスト形式
    • XML
    • JSON
  • バイナリ形式
    • Google プロトコル バッファ
    • メッセージパック

これらにはすべて長所と短所があります。私は特にMessagePackが好きで、ぜひご覧になることをお勧めします。たとえば、自己記述型の を格納するために 9 バイトを使用しますdouble

于 2013-05-22T18:08:46.270 に答える