首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在协议缓冲区中使用小数和日期时间的最佳方法是什么?

在协议缓冲区中使用小数和日期时间的最佳方法是什么?
EN

Stack Overflow用户
提问于 2009-09-30 09:49:48
回答 4查看 9.3K关注 0票数 11

我想找出存储一些不包括在协议缓冲区支持的列表中的公共数据类型的最佳方法是什么。

  • 日期时间(秒精度)
  • 日期时间(毫秒精度)
  • 固定精度的小数
  • 变精度小数
  • 大量的bool值(如果您有很多它们,那么由于它们的标记,每个值都会有1-2字节的开销)。

此外,其思想是很容易地映射它们,以对应C++/Python/Java数据类型。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2009-12-24 10:44:18

protobuf设计原理最有可能将数据类型支持尽可能地保持为“原生”,这样以后就很容易采用新的语言。我想他们可以提供内置消息类型,但是您在哪里划定了界限呢?

我的解决方案是创建两种消息类型:

代码语言:javascript
复制
DateTime
TimeSpan

这仅仅是因为我来自C#背景,在那里这些类型被认为是理所当然的。

回想起来,TimeSpanDateTime可能有些过火,但这是避免从h/m/s转换为s的“廉价”方法,反之亦然;也就是说,只实现以下实用程序函数就很简单了:

代码语言:javascript
复制
int TimeUtility::ToSeconds(int h, int m, int s)

Bklyn指出堆内存用于嵌套消息;在某些情况下,这显然非常有效--我们应该始终知道内存是如何使用的。但是,在其他情况下,我们更担心的是实现的易用性(我认为这是Java/C#的哲学)。

在protobuf TextFormat::Printer中使用非内部类型也有一个小缺点;您不能指定显示它的格式,因此它看起来如下所示:

代码语言:javascript
复制
my_datetime {
    seconds: 10
    minutes: 25
    hours: 12
}

..。对某些人来说太冗长了。也就是说,如果以秒为单位来表示,就很难读懂它。

总结,我想说:

  • 如果您担心内存/解析效率,请使用秒/毫秒。
  • 但是,如果目标是易于实现,则使用嵌套消息(DateTime等)。
票数 3
EN

Stack Overflow用户

发布于 2009-11-18 21:11:16

下面是一些基于我使用类似于协议缓冲区的有线协议的经验的想法。

日期时间(秒精度) 日期时间(毫秒精度)

我认为这两个问题的答案是一样的,在秒精度的情况下,你通常只需要处理一个较小的数字范围。

使用sint64 64/ some 64存储偏移量(以秒/毫秒为单位),以秒/毫秒为单位,以秒/毫秒的速度存储一些著名时代的偏移量,如格林尼治时间1/1/1970午夜。这就是日期对象是内部用Java表示的方式。我确信Python和C++中有类似的东西。

如果您需要时区信息,按照UTC传递您的日期/时间,并将相关的时区建模为一个单独的字符串字段。为此,您可以使用来自Olson Zoneinfo数据库的标识符,因为这已经成为某种标准。

这样,您就有了日期/时间的规范表示,但也可以本地化到任何相关的时区。

固定精度的小数

我的第一个想法是使用类似于从Python的十进制包中构造Decimal对象的字符串。我认为相对于某些数值表示而言,这可能是无效的。

可能有更好的解决方案取决于您正在使用的域。例如,如果您正在建模一个货币值,也许您可以使用uint32 32/64来传递以美分为单位的值,而不是小数美元金额。

这条线中也有一些有用的建议。

变精度小数

协议缓冲区不支持浮动/双标量类型吗?也许我误解了这点。

无论如何,如果您需要绕过这些标量类型,您可以使用IEEE-754对uint32或uint64进行编码(浮点数分别对双)。例如,来自浮动/双对象的Java 允许提取IEEE-754表示形式。反之亦然。在C++/Python中有类似的机制。

大量的bool值(如果您有很多它们,那么由于它们的标记,每个值都会有1-2字节的开销)。

如果您担心线路上浪费的字节,可以使用比特掩蔽技术将许多布尔值压缩为单个uint32或uint64。

因为协议缓冲区中没有一流的支持,所以所有这些技术都需要代理之间的一些绅士契约。在您的字段上使用命名约定(如"_dttm“或"_mask”)可能有助于在给定字段除了协议缓冲区的默认行为之外具有额外的编码语义时进行通信。

票数 3
EN

Stack Overflow用户

发布于 2009-10-14 22:26:44

对不起,不是完整的回答,而是“我也是”。

我认为这是一个很好的问题,我很想给自己一个答案。对于我来说,无法本土地描述日期时间和(金融应用)定点小数之类的基本类型,或者将它们映射到语言指定的或用户定义的类型,对我来说是一个真正的杀手。它或多或少地阻止了我能够使用图书馆,否则我认为这是很棒的。

在proto语法中声明自己的"DateTime“或"FixedPoint”消息并不是真正的解决方案,因为您仍然需要手动将平台的表示形式转换为/从生成的对象中转换,这很容易出错。此外,这些嵌套消息被存储为指向C++中堆分配对象的指针,当底层类型基本上只是64位整数时,这是非常低效率的。

具体来说,我希望能够在我的proto文件中编写这样的东西:

代码语言:javascript
复制
message Something {
   required fixed64 time = 1 [cpp_type="boost::posix_time::ptime"];
   required int64 price = 2 [cpp_type="fixed_point<int64_t, 4>"];
   ...
 };

我需要提供将这些类型转换为/从fixed64和int64转换所需的任何胶水,这样序列化才能正常工作。也许是通过类似于adobe::促进的方式

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1497116

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档