Как я могу ускорить десериализацию MongoDB для C # - PullRequest
2 голосов
/ 29 января 2012

При возврате многих результатов из запроса коду требуется очень много времени для преобразования данных в объекты .net.Это базовые объекты с несколькими строками в виде полей.Я не уверен, но я думаю, что он использует отражение для создания экземпляров, что медленно.Есть ли способ ускорить это?

Ответы [ 3 ]

2 голосов
/ 30 января 2012

Драйвер 10gen не использует отражение для каждого объекта. Он использует отражение один раз для каждого типа для генерации сериализатора с использованием Reflection.Emit, поэтому сериализация или десериализация первого объекта может быть медленной, но любые объекты впоследствии будут быстрыми (относительно).

Ваш вопрос - есть ли способ ускорить это?

Если ваши объекты простые (не вложенные документы, несколько открытых полей и т. Д.), То, вероятно, вы ничего не сможете сделать. Вы могли бы реализовать собственный сериализатор для класса, чтобы добиться небольшой производительности, но я сомневаюсь, что это будет более чем на несколько процентов.

Я не рассматривал это, и Роберт Стам (который также ответил на этот вопрос) был бы авторитетом в этом вопросе, но может быть достигнута некоторая производительность в многоядерных или многопроцессорных системах путем распараллеливания десериализации в драйвере. Я еще не рассматривал код драйвера с этой точки зрения, так что, возможно, Роберт уже этим занимался.

В целом, я думаю, что 30 000 объектов за 10 секунд - это достаточно стандартное решение практически для любой платформы - SQL, Mongo, XML и т. Д., В которой объекты не хранятся непосредственно в виде больших двоичных объектов памяти (как вы могли бы использовать такой язык, как C ++). ).

EDIT:

Похоже, что драйвер 10gen выполняет десериализацию, прежде чем возвращает курсор для перечисления. Поэтому, если ваш запрос возвращает 30 000 результатов, все 30 000 объектов должны быть десериализованы, прежде чем драйвер сделает курсор доступным для перечисления. Я не смотрел на драйвер jmongo, но я ожидаю, что он делает противоположное и откладывает десериализацию до тех пор, пока объект не будет перечислен в курсоре.

Чистый результат заключается в том, что, хотя для того, чтобы перечислить и десериализовать 30 000 объектов, возможно, потребуется одинаковое общее время, десериализация в драйвере jmongo распространяется по всему перечислению, где в драйвере c # он загружается с фронта.

Разница невелика, но, вероятно, объясняет то, что вы видите.

Плохая новость заключается в том, что «исправление» - это смена драйвера. Одна вещь, которую вы можете сделать, это разбить ваш запрос на куски, запрашивая 10 или 100 объектов одновременно

2 голосов
/ 30 января 2012

Не уверен, как вы измеряете. Когда драйвер C # возвращает пакет документов с сервера, он сразу десериализует их все, поэтому первый документ может запаздывать, но тогда остальные документы будут действительно быстрыми. Что действительно важно, так это общая пропускная способность, выраженная в единицах документов в секунду, и то, достаточно ли она достаточна для насыщения сетевого канала.

Хотя для многих стандартных классов .NET существуют жестко закодированные сериализаторы, сериализация POCO обычно выполняется с помощью карт классов. Отражение используется для построения карт классов, но отражение больше не требуется при выполнении сериализации / десериализации.

Вы могли бы немного ускорить сериализацию / десериализацию, написав свои собственные сериализаторы с ручным кодированием для ваших классов (или заставив ваши классы реализовать IBsonSerializable), но, поскольку узкое место, вероятно, является сетью в любом случае, оно, вероятно, того не стоит.

0 голосов
/ 30 января 2012

Вот что я использую:

  1. Чтение только необходимых полей
  2. Кэширование объектов, которые часто необходимы, но редко меняются в памяти
  3. Когда мне нужночитать много объектов по правилу (например, товары по критериям фильтра). Я храню все товары в одном объекте фильтра и читаю их все сразу.Недостатком является пересчет этого кэша, когда что-то изменилось.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...