C# Protobuf Net的实现能比我目前拥有的更好吗?

C# Protobuf Net的实现能比我目前拥有的更好吗?,c#,collections,binary,protobuf-net,C#,Collections,Binary,Protobuf Net,我之前发布了一个关于Protobuf Net的相关但仍然不同的问题,下面是: 我想知道是否有人(特别是马克)可以评论以下哪项最有可能更快: (a) 我目前将序列化的内置数据类型存储在二进制文件中。具体来说,一个长(8字节)和两个浮点(2x4字节)。之后,其中的每3个组成一个处于反序列化状态的对象。长类型表示用于查找的DateTimeTicks。我使用二进制搜索来查找数据请求的开始和结束位置。然后,一个方法将数据下载到一个块中(从开始位置到结束位置),知道每个块由许多上述三元组(1长、1浮点数、1

我之前发布了一个关于Protobuf Net的相关但仍然不同的问题,下面是:

我想知道是否有人(特别是马克)可以评论以下哪项最有可能更快:

(a) 我目前将序列化的内置数据类型存储在二进制文件中。具体来说,一个长(8字节)和两个浮点(2x4字节)。之后,其中的每3个组成一个处于反序列化状态的对象。长类型表示用于查找的DateTimeTicks。我使用二进制搜索来查找数据请求的开始和结束位置。然后,一个方法将数据下载到一个块中(从开始位置到结束位置),知道每个块由许多上述三元组(1长、1浮点数、1浮点数)组成的数据包组成,并且每个三元组总是16字节长。因此,检索到的三元组数始终为(endLocation-startLocation)/16。然后,我迭代检索到的字节数组,反序列化(使用位转换器)每个内置类型,然后实例化一个由每个三元组组成的新对象,并将对象存储在列表中以供进一步处理

(b) 这样做会更快吗?构建一个单独的文件(或实现一个头文件),作为查找目的的索引。然后,我不会存储内置类型的单个二进制版本,而是使用Protbuf net序列化上述对象的列表(=int、float、float作为对象源的三元组)。每个列表都将精确且始终包含一天的数据(请记住,long代表DateTimeTick)。显然,每个列表的大小会有所不同,因此我的想法是为索引查找目的生成另一个文件或头,因为每个数据读取请求只会请求整天的倍数。当我想要检索某一天的序列化列表时,我只需查找索引,读取字节数组,使用Protobuf Net反序列化,并且已经有了对象列表。我想我之所以这么问是因为我不完全理解protobuf网络中集合的反序列化是如何工作的

为了更好地了解数据量,每个二进制文件大约3gb大,因此包含数百万个序列化对象。每个文件包含大约1000天的数据。每个数据请求可以请求任何数量的一天数据

您认为什么样的原始处理时间更快?在可能编写大量代码来实现(b)之前,我想获得一些输入,目前我有(a),并且能够在我的机器上每秒处理大约150万个对象(process=从数据请求到返回的反序列化对象列表)

小结:我想问的是,使用(a)或(b)方法是否可以更快地读取I/O和反序列化二进制数据

我认为每天使用一个“块”和一个索引是一个好主意,因为只要每条记录的大小为16字节,它就可以让您进行随机访问。如果有一个索引跟踪文件中每天的偏移量,还可以使用创建特定日期或日期范围内数据的快速视图

协议缓冲区的一个好处是,它们使固定大小的数据大小可变,因为它压缩值(例如,使用一个字节写入长的零值)。这可能会给您带来一些在海量数据中随机访问的问题

我不是protobuf专家(我有一种感觉,Marc将在这里向您介绍),但我的感觉是,协议缓冲区确实最适合作为一个整体(或至少在整个记录中)访问的中小型非平凡结构化数据卷。对于非常大的随机访问数据流,我认为不会有性能提升,因为当不同的记录可能被压缩不同的量时,您可能会失去进行简单随机访问的能力

我认为每天使用一个“块”和一个索引是一个好主意,因为只要每条记录的大小为16字节,它就可以让您进行随机访问。如果有一个索引跟踪文件中每天的偏移量,还可以使用创建特定日期或日期范围内数据的快速视图

协议缓冲区的一个好处是,它们使固定大小的数据大小可变,因为它压缩值(例如,使用一个字节写入长的零值)。这可能会给您带来一些在海量数据中随机访问的问题

我不是protobuf专家(我有一种感觉,Marc将在这里向您介绍),但我的感觉是,协议缓冲区确实最适合作为一个整体(或至少在整个记录中)访问的中小型非平凡结构化数据卷。对于非常大的随机访问数据流,我认为不会有性能提升,因为当不同的记录可能被压缩不同的量时,您可能会失去进行简单随机访问的能力

我目前将序列化的内置数据类型存储在二进制文件中。具体来说,一个长(8字节)和两个浮点(2x4字节)

您所拥有的是(无意冒犯)一些非常简单的数据。如果你喜欢处理原始数据(听起来你也喜欢),那么我觉得最好的处理方法就是:照你自己的样子处理。偏移量是16的干净倍数,以此类推

协议缓冲区通常(不仅仅是protobuf net,它是protobuf规范的单一实现)用于更复杂的场景集:

  • 嵌套/结构化数据(想想:xml即复杂记录,而不是csv即简单记录)
  • 可选字段(数据中可能根本不存在某些数据)
  • 可扩展/版本容忍(可能存在意外值或半预期值)
    • 特别是,可以在不中断字段的情况下添加/弃用字段
  • 基于跨平台/模式的
  • 最终用户不需要参与任何序列化细节
这是一个有点不同的用例!像