Deserializing Protobuf-Net objects using a filter
我在我们的一个项目中使用 protobuf-net 来序列化/反序列化大量同类对象。它工作得很好,速度也很棒。不过只有一个问题。反序列化时是否可以使用 linq(或任何其他机制)来指定过滤条件,以便加载仅满足该条件的对象?反序列化所有对象然后应用 linq 过滤器相当简单,但我想减少加载到内存中的对象数量。过滤条件可以是相当动态的,所以字符串类型的机制会很棒(类似于 dlinq?)。
没有什么内置的,但是如果你有一个明确定义的用例,我当然可以看看(我是作者)。
现在,我建议使用以下变体:
1 2 3 4 | var found = Serializer.DeserializeItems<A>(source, PrefixStyle.Base128, Serializer.ListItemTag).FirstOrDefault(obj => obj.Foo ="bar"); if(found != null) {...} |
找到匹配项时会短路,并会立即释放对象以进行收集(希望在 gen-0 中)。或者对于多个项目,也许:
1 2 | var list = Serializer.DeserializeItems<A>(source, PrefixStyle.Base128, Serializer.ListItemTag).Where(obj => obj.Foo ="bar").ToList(); |
(再次立即释放不匹配的项目)
要在一般情况下执行此操作(尤其是对于更复杂的查询),如果不实现对象,我想不出一种理智的方法来做到这一点,所以这可能是你能得到的最接近的,除非有一个非常恰好与底层数据存储很好地对齐的特定(和简单)场景(例如,过滤器始终位于 "tag 1")。
通常,在完成反序列化之前,您不能将序列化数据视为原始数据以外的任何内容。
您可能会从过滤中获得一些内存优势,但除非这是一个问题,否则不值得打扰。
您可以过滤传入的序列化表示,但要权衡执行此操作的时间和精力与您将节省的内容。
大多数情况下(在桌面或服务器环境中)最好选择可行的简单选项,然后在以后需要时使用更复杂的选项。