使用protobuf-net进行质量过滤

我用protobuf-net序列化了一个对象列表。

从理论上讲,.bin文件可以包含数百万个对象。

假设对象属于包含以下内容的类:

public string EventName; 

我必须进行查询并创建一个包含与查询匹配的对象的列表。 使用LINQ从序列化文件中提取匹配对象的正确方法是什么?

protobuf格式是项目的线性序列; 任何索引等你只能单独申请。 但是, IEnumerable可用; 你可能会发现:

 var item = Serializer.DeserializeItems(source) .First(item => item.Id == id); 

做得很好; 这个:

  • 懒洋洋地假装; 每个项目都是单独产生的,因此您不需要大量的内存
  • 短路; 如果在开始附近找到该项目,它将立即退出

或者对于多个项目:

 var list = Serializer.DeserializeItems(source) .Where(item => item.Foo == foo); 

(如果要缓冲内存中的匹配项,请在上面添加ToList,如果只想以仅前向方式解析一次,则使用不带ToList)

如果你想在选定的元素列表上添加一些投影,你应该尝试我的库, https://github.com/Scooletz/protobuf-linq 。 它们也可以在NuGet上使用。 该库极大地降低了反序列化的开销。 在某些情况下,它可以降至原始查询的50%。

不幸的是,没有一个。 为了使用LINQ,您的对象必须实现IQueryableIEnumerable 。 除非有一个可以在.bin文件中提供IQueryable接口的LINQ提供程序,否则你必须:

  • 将文件反序列化到内存中并使用LINQ-to-objects IEnumerable
  • 编写可以提供IQueryable的LINQ提供程序(如果你的文件是巨大的,这可能是唯一可行的选项)可以处理文件而不加载整个文件。

protobuf可以将文件的内容作为流IEnumerable提供给您,因此您可以轻松地执行此操作。 不幸的是我不知道如何调用该方法,但在文档中很容易找到。