プロトコルバッファー:.NET DateTime値を表すには、int64またはfixed64を使用する必要がありますか?
-
10-07-2019 - |
質問
プロトコルバッファメッセージの.NET DateTime値をシリアル化する必要があります。
私の計画では、DateTime.ToBinary()を使用してから、メッセージで64ビットの戻り値を渡します。しかし、それを表すためにプロトコルがデータ型をバッファリングするので、何を選ぶべきか分かりません。
fixed64(またはsfixed64)データ型を使用する必要がある場合について混乱していると思います。
DateTime.ToBinary()によって返される値は負でも正でもあり得るため、このシナリオでは符号付きの型を使用すると想定しています。
解決
まあ、あなたは間違いなく int64
または sfixed64
のいずれかが署名された値に対処することを望みます。
簡単なテストを終えたばかりの DateTime.Now.ToBinary()
は int64
を使用して10バイトでエンコードされますが、 sfixed64
は常に8バイト。基本的に、可変長エンコーディングは小さな数値には適していますが、大きな数値の固定エンコーディングよりも大きくなります。 (UTF-16の代わりにUTF-8を使用するのと同じ種類のトレードオフです-ASCII文字はシングルバイトでUTF-8でエンコードできますが、後でコードポイントは2バイトと3バイトとしてエンコードされますが、UTF -16は、BMPの文字に常に2バイトを使用します。)
私の推測では、 DateTime.ToBinary()
の値は可能性が高いである可能性が非常に高い(正確に何を行うのかを知らずに)ので、 sfixed64
の方が適切です。
それは理にかなっていますか
他のヒント
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
}
}
i.e。 DateTime
を丸1日で表現できる場合は、1970年以降の日数などに加えて、小さなマーカーをスケールに送信します。これは、日付をもう少し効率的に送信できることを意味しますが、実際には他のスケールではそれほどコストはかかりません。
個人的に、 ToBinary()
は使用しません-既知のエポック(unixエポックなど)からの既知のスケールのオフセットを明示的に使用します。これにより、プラットフォーム間での移植性が向上します。ただし、(たとえば)ミリ秒のオフセットだけを送信している場合、通常、可変長スケールよりも固定スケールの方が効率的です。署名が必要かどうかは、エポックより前の日付が必要かどうかによって異なります;-p
DateTime
が負になる可能性があるためではなく、 ToBinary
メソッドが Int64
を返すため、符号付き64ビット数を使用する必要があります、署名された64ビットの数値です。