XML против двоичной производительности для сериализации / десериализации
========================================================================

Я работаю над компактным каркасным приложением, и мне нужно повысить производительность. В настоящее время приложение работает в автономном режиме, выполняя сериализацию объектов в XML и сохраняя их в базе данных. Используя инструмент профилирования, я мог видеть, что это было довольно большой нагрузкой, замедляющей работу приложения. Я думал, что если я переключусь на двоичную сериализацию, производительность увеличится, но поскольку это не поддерживается в компактной среде, я посмотрел на protobuf-net. Сериализация кажется более быстрой, но десериализация намного медленнее, и приложение выполняет больше десериализации, чем сериализации.

Должна ли двоичная сериализация быть быстрее, и если да, что я могу сделать, чтобы повысить производительность? Вот фрагмент того, как я использую и XML, и бинарный файл:

XML сериализация:

Бинарная сериализация Protobuf-net:

Основным расходом в вашем методе является фактическая генерация класса XmlSerializer. Создание сериализатора - это длительный процесс, который вы должны выполнять только один раз для каждого типа объекта. Попробуйте кэшировать сериализаторы и посмотреть, не улучшит ли это вообще производительность.

Следуя этому совету, я увидел значительное улучшение производительности своего приложения, что позволило мне продолжать использовать сериализацию XML.

Надеюсь это поможет.



XML часто медленно обрабатывается и занимает много места. Было предпринято несколько различных попыток решить эту проблему, и наиболее популярной сегодня, похоже, является просто сбросить пакет в файл gzip, как в случае с[Конвенция об открытой упаковке](https://en.wikipedia.org/wiki/Open_Packaging_Conventions).

[W3C](https://www.w3.org/XML/EXI/) показал, что подход gzip меньше оптимального, и они и различные[другие группы](https://en.wikipedia.org/wiki/Binary_XML) работали над улучшением двоичной сериализации, подходящей для быстрой обработки и сжатия, для передачи.



Я собираюсь исправить себя, Марк Гравалл отметил, что на первой итерации накладывается нагрузка на модель, поэтому я провел несколько тестов, в которых принималось в среднем 1000 итераций сериализации и десериализации как для XML, так и для двоичного кода. Я попробовал свои тесты с v2 из Compact Framework DLL, а затем с v3.5 DLL. Вот что я получил, время в мс:



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

Имейте в виду, что измерения производительности, опубликованные Marc Gravell, тестируют производительность более 1 000 000 итераций.

В какой базе данных вы храните их? Сериализуются ли объекты в памяти или прямо в хранилище? Как их отправляют в БД? Насколько большие объекты? При обновлении отправляете ли вы все объекты в базу данных или только тот, который изменился? Вы вообще что-то кешируете в памяти или перечитываете из памяти каждый раз?



Интересные ... мысли

* what version of CF is this; 2.0? 3.5? In particular, CF 3.5 has `Delegate.CreateDelegate` that allows protobuf-net to access properties much faster than in can in CF 2.0
* are you annotating *fields* or *properties*? Again, in CF the reflection optimisations are limited; you can get beter performance in CF 3.5 with *properties*, as with a field the only option I have available is `FieldInfo.SetValue`

Есть ряд других вещей, которые просто не существуют в CF, поэтому он должен идти на компромиссы в нескольких местах. Для слишком сложных моделей есть также[известная проблема с ограничениями дженериков CF](https://marcgravell.blogspot.com/2009/03/compact-framework-woes-revisted.html), Исправление идет полным ходом, но это**big** изменить, и занимает "некоторое время".

Для информации, некоторые метрики на обычном (полном) .NET сравнивают различные форматы (включая`XmlSerializer` и протобуф-нет)[здесь](https://code.google.com/p/protobuf-net/wiki/Performance).



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

Если у вас есть Visual Studio, этот параметр доступен на вкладке «Построение» свойств вашего проекта.