协议缓冲区:我应该使用int64或fixed64来表示.NET DateTime值吗?

时间:2009-05-07 23:21:20

标签: .net serialization protocol-buffers

我需要在协议缓冲区消息中序列化.NET DateTime值。

我的计划是使用DateTime.ToBinary(),然后在消息中传递64位返回值。但我不确定选择什么作为协议缓冲数据类型来表示它。

我想我应该在使用fixed64(或sfixed64)数据类型时对感到困惑。

我假设在这种情况下我会使用签名类型,因为DateTime.ToBinary()返回的值可以是负数也可以是正数。

3 个答案:

答案 0 :(得分:9)

嗯,您肯定希望int64sfixed64能够应对正在签名的值。

刚刚进行了快速测试,DateTime.Now.ToBinary()使用int64以10个字节进行编码,而sfixed64将始终使用8个字节。基本上,可变长度编码对于小数字很有用,但是对于大数字而言变得比固定编码大。 (这与使用UTF-8而不是UTF-16的权衡相同 - ASCII字符可以在单个字节中以UTF-8编码,但稍后在代码点上最终编码为2然后3个字节,而UTF -16总是在BMP中使用2个字节作为字符。)

我的猜测是DateTime.ToBinary()可能非常大(不知道其具体内容的详细信息),因此sfixed64更合适。

这有意义吗?

答案 1 :(得分: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

答案 2 :(得分:0)

您应该使用带符号的64位数字,而不是因为DateTime可能是负数,而是因为ToBinary方法返回Int64,这是一个带符号的64位数字