7

プロトコルバッファメッセージで.NETDateTime値をシリアル化する必要があります。

私の計画では、DateTime.ToBinary()を使用してから、64ビットの戻り値をメッセージに渡します。しかし、それを表すためにプロトコルバッファデータ型として何を選択すればよいかわかりません。

fixed64(またはsfixed64)データ型をいつ使用すべきかについて混乱していると思います。

このシナリオでは、DateTime.ToBinary()によって返される値が正の場合も負の場合もあるため、符号付きの型を使用すると想定しています。

4

3 に答える 3

9

まあ、あなたは間違いなく、int64またはsfixed64署名されている値に対処したいと思っています。

簡単なテストを行ったところ、常に 8 バイトを使用するのに対しDateTime.Now.ToBinary()、10 バイトでエンコードされます。基本的に、可変長エンコーディングは小さな数値には優れていますが、大きな数値では固定エンコーディングよりも大きくなります。(これは、UTF-16 の代わりに UTF-8 を使用するのと同じ種類のトレードオフです。ASCII 文字は UTF-8 で 1 バイトにエンコードできますが、後でコード ポイントは 2 バイト、次に 3 バイトとしてエンコードされますが、UTF は-16 は、BMP の文字に常に 2 バイトを使用します。)int64sfixed64

私の推測では、DateTime.ToBinary()値は非常に大きくなる可能性が高いため (それが何をするかの詳細を知らなくても)、sfixed64より適切です。

それは理にかなっていますか?

于 2009-05-07T23:31:54.317 に答える
4

protobuf-netでは、段階的なスケール アプローチを使用します (実際、単純に を使用すると、これらすべてが処理されますDateTime)。同等の .proto は次のようなものです。

message DateTime {
  optional sint64 value = 1; // the offset (in units of the selected scale)
                             // from 1970/01/01
  optional TimeSpanScale scale = 2 [default = DAYS]; // the scale of the
                                                     // timespan
  enum TimeSpanScale {
    DAYS = 0;
    HOURS = 1;
    MINUTES = 2;
    SECONDS = 3;
    MILLISECONDS = 4;

    MINMAX = 15; // dubious
  }
}

つまりDateTime、丸一日で表すことができる場合は、1970 年以降の日数と、スケールに小さなマーカーを追加するだけです。これは、日付をもう少し効率的に送信できることを意味しますが、他のスケールではそれほどコストがかかりません.

個人的には、私は使用しませんToBinary()。既知のエポック (UNIX エポックなど) からの既知のスケールのオフセットを明示的に使用します。これにより、プラットフォーム間での移植性が向上します。ただし、(たとえば) ミリ秒のオフセットだけを送信する場合は、通常、可変長スケールよりも固定スケールの方が効率的です。署名付きまたは署名なしが必要かどうかは、エポックより前の日付が必要かどうかによって異なります;-p

于 2009-05-08T04:28:06.743 に答える
0

DateTimeが負になる可能性があるためではなく、ToBinaryメソッドが符号付き64ビット数であるを返すため、符号付き64ビット数を使用する必要がありますInt64

于 2009-05-07T23:27:29.057 に答える