Массовая фильтрация с протобуф-сеткой - PullRequest
5 голосов
/ 14 февраля 2011

Я сериализовал список объектов с помощью protobuf-net.

Теоретически файл .bin может содержать миллионы объектов.

Предположим, что объекты принадлежат классу, содержащему следующие:

public string EventName;

Я должен принять запрос и создать список, содержащий объекты, соответствующие запросу.Как правильно извлечь соответствующие объекты из сериализованного файла с помощью LINQ?

Ответы [ 4 ]

5 голосов
/ 14 февраля 2011

Формат 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 в конец вышеупомянутого, если вы хотите буферизовать соответствующие элементы в памяти, или использовать без ToList, если вы просто хотите разобрать его один раз только для пересылки)

1 голос
/ 22 июня 2013

Если вы хотите добавить проекцию в выбранный список элементов, попробуйте мою библиотеку, https://github.com/Scooletz/protobuf-linq. Они также доступны в NuGet.Библиотека значительно снижает накладные расходы на десериализацию.В некоторых случаях он может упасть до 50% от исходного запроса.

0 голосов
/ 14 февраля 2011

protobuf может предоставить вам содержимое файлов в виде потоковой передачи IEnumerable<T>, так что вы можете легко это сделать.К сожалению, я не знаю, как вызывается метод, но его легко найти в документации.

0 голосов
/ 14 февраля 2011

К сожалению, нет ни одного.Чтобы использовать LINQ, ваш объект должен реализовывать либо IQueryable<T>, либо IEnumerable<T>.Если у вас нет поставщика LINQ, который может предоставить IQueryable<T> интерфейс для вашего .bin-файла, вам придется либо:

  • десериализовать файл в память и использовать LINQ-to-objects IEnumerable<T>
  • Напишите вашему поставщику LINQ, который может предоставить IQueryable<T> (и это, вероятно, единственный практический вариант, если ваш файл ОГРОМНЫЙ), который может обработать файл, не загружая все это.
...