使用 protobuf-net 进行质量过滤

发布于 2024-10-17 12:13:45 字数 212 浏览 5 评论 0原文

我已经使用 protobuf-net 序列化了对象列表。

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

让我们假设这些对象属于包含以下内容的类:

public string EventName;

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

I have serialized a list of objects with protobuf-net.

Theoretically, the .bin file can contain millions of objects.

Let's assume the objects are of a class containing the following:

public string EventName;

I have to take a query and create a list containing the objects matching the query.
What is the correct way to extract the matching objects from the serialized file using LINQ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

谁把谁当真 2024-10-24 12:13:45

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

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

工作做得很好; this:

  • 被懒惰地假脱机;每个项目都是单独生成的,因此您不需要内存过剩
  • 而短路;如果在开头附近找到该项目,它将立即退出

或者对于多个项目:(

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

如果您想在内存中缓冲匹配的项目,则在上面的末尾添加一个ToList,或者如果您只是想在没有ToList的情况下使用以仅向前的方式解析一次)

The protobuf format is a linear sequence of items; any indexing etc you way can only be applies separately. However, IEnumerable<T> is available; you might find that:

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

does the job nicely; this:

  • is lazily spooled; each item is yielded individually, so you don't need a glut of memory
  • is short-circuited; if the item is found near the start, it'll exit promptly

Or for multiple items:

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

(add a ToList to te end of the above if you want to buffer the matching items in memory, or use without a ToList if you just want to parse it once in a forwards-only way)

水晶透心 2024-10-24 12:13:45

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

If you want to add some projection over the selected list of elements you should try a library of mine, https://github.com/Scooletz/protobuf-linq. They are available on NuGet as well.
The library lowers overhead of deserialization greatly. In some cases it can drop to 50% of the original query.

撩起发的微风 2024-10-24 12:13:45

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

  • 将文件反序列化到内存中并使用 LINQ-to-objects IEnumerable
  • 编写您的 LINQ 提供程序,它可以提供一个 IQueryable(如果您的文件很大,这可能是唯一实用的选择),它可以在不加载整个事情。

Unfortunately, there isn't one. In order to use LINQ, your object must implement either IQueryable<T> or IEnumerable<T>. Unless there is a LINQ provider that can provide an IQueryable<T> interface into your .bin file, you'll either have to:

  • Deserialize the file into memory and use LINQ-to-objects IEnumerable<T>
  • Write your LINQ provider that can provide an IQueryable<T> (and this is likely the only practical option if your file is HUGE) that can process the file without loading the whole thing.
淑女气质 2024-10-24 12:13:45

protobuf 可以以流式 IEnumerable 形式为您提供文件内容,因此您可以轻松做到这一点。不幸的是,我不知道如何调用该方法,但很容易在文档中找到它。

protobuf can give you the contents of the files as a streaming IEnumerable<T>, so you can easily do that. Unfortunately I do not know how the method is called but it is easy to find in the docs.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文