使用protobuf-net进行质量过滤

问题描述:

我使用protobuf-net序列化了一系列对象。使用protobuf-net进行质量过滤

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

假设的目的是含有以下一类:

public string EventName; 

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

protobuf格式是一个项目的线性序列;任何索引等你的方式只能分开申请。但是,IEnumerable<T>可用;您可能会发现:

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

很好地完成了这项工作;这个:

  • 是懒洋洋的假脱机;每个项目单独产生,因此您不需要内存过剩
  • 被短路;如果该项目被发现在附近展开,它会迅速退出

或者多个项目:

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

(如果你希望缓冲相匹配的项目添加ToList以上的TE结束在内存中,或者在没有ToList的情况下使用,如果你只想以forwards-only的方式解析它)

不幸的是,没有一个。为了使用LINQ,您的对象必须实现IQueryable<T>IEnumerable<T>。除非有LINQ提供程序可以提供IQueryable<T>接口到您的.bin文件,你要么必须:

  • 反序列化文件到内存中,并使用LINQ到对象IEnumerable<T>
  • 写下您的LINQ提供者可以提供IQueryable<T>(如果文件很大,这可能是唯一可行的选择),它可以在不加载整个文件的情况下处理文件。
+0

DeserializeItems提供了一个好的工作`IEnumerable `API,然后 – 2011-02-14 19:29:47

+0

@Marc:它会出现这样!我假定反序列化会将整个文件加载到内存中。很明显,我错了。 – 2011-02-14 19:51:04

+0

它会懒惰地从流中缓存它们(`yield return`) - 处理大数据量的理想选择 – 2011-02-14 19:55:41

protobuf可以给你的文件内容作为流IEnumerable<T>,所以你可以很容易地做到这一点。不幸的是,我不知道如何调用该方法,但在文档中很容易找到。

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