使用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,您的对象必须实现IQueryable
或IEnumerable
。 除非有一个可以在.bin文件中提供IQueryable
接口的LINQ提供程序,否则你必须:
- 将文件反序列化到内存中并使用LINQ-to-objects
IEnumerable
- 编写可以提供
IQueryable
的LINQ提供程序(如果你的文件是巨大的,这可能是唯一可行的选项)可以处理文件而不加载整个文件。
protobuf可以将文件的内容作为流IEnumerable
提供给您,因此您可以轻松地执行此操作。 不幸的是我不知道如何调用该方法,但在文档中很容易找到。