Код Serbench находится на GitHub. .
Начало проекта
Этот эталонный проект начался со статьи « Сериализаторы в .NET v.2
» на GeeksWithBlogs.net. В статье было рассмотрено довольно много сериализаторов, доступных для .NET. Но чтобы превратить эту статью и соответствующий код в настоящий эталон, необходимо было внести несколько улучшений.
Во-первых, сериализаторы пришлось протестировать на нескольких типах данных.
Есть сериализаторы универсальные, а есть специализированные.
Специализированные очень хорошо работают лишь с несколькими типами данных; по другим данным они работают гораздо хуже или не работают вообще.
В этом мы позже убедились.
Во-вторых, сериализаторы сильно различаются по своим интерфейсам.
Наш тест не должен заставлять сериализатор следовать нашему выбору интерфейса.
Напротив, тест должен быть настолько гибким, чтобы каждый сериализатор мог использовать тот интерфейс, который ему лучше всего подходит. То есть вам нужно передать в бенчмарк дополнительные параметры конкретного сериализатора.
К автору статьи Автор одного из сериализаторов обратился ко мне с предложением сделать улучшенный тест. Автор сериализатора был инициатором этого проекта, он же был и ведущим разработчиком.
Сергей был разработчиком всей веб-части проекта, все доклады отличные.
Эталонной платформой была НФКС , что позволило нам сделать всё запланированное (и многое-многое другое) очень быстро.
У NFX есть сотни подобных статей, надеюсь, они вас тоже заинтересуют.
Представление результатов испытаний
Для начала немного остановлюсь на представлении результатов, на том, что требует особого внимания.
Для примера посмотрим на сводную информацию одного из тестов:
Слева мы увидим трех победителей в двух наиболее важных категориях: скорость и размер сериализованных данных.
Сразу оговорюсь, что победителей может быть больше, что победителями можно считать все сериализаторы, попадающие в синюю, зеленую и в меньшей степени светло-коричневую категории.
Серая категория — это сериализаторы, которые не прошли этот тест. В столбце скорости вы можете нажать на имя сериализатора и получить разбивку скорости с отдельными числами для сериализации и десериализации.
За основную берется худшая скорость из сериализации и десериализации.
Мы предполагаем, что вас волнует общая производительность системы, а не производительность только сериализации или только десериализации.
Ваш случай может быть другим, поэтому на графике тонкой палочкой также указана скорость другой операции.
Что искать:
- Для сериализаторов, которые не прошли тест:
Если вы выбираете для работы «быстрый» сериализатор, и он повреждает ваши данные, это худшее, что можно себе представить.
Вы потратите много времени, пытаясь понять причину искажения данных.
И вам повезет, если вы наткнетесь на это в разработке, а не в производстве.
- Чтобы проверить, соответствуют ли ваши данные тестовым данным:
Никогда не доверяйте своей интуиции, никогда не доверяйте экстраполяции.
Практически любой сериализатор аварийно завершает работу при определенном размере данных.
Предельные испытания мы не проводили, делайте их самостоятельно по вашим данным.
Очень немногие сериализаторы прошли все наши тесты.
Внимание! Далее по тексту вы постоянно будете встречать слова «обычно», «чаще всего» и т. д. Приношу извинения за это и понимаю, что это делает результаты теста несколько неопределенными.
Надеюсь, вы также понимаете, что результаты тестов не должны показать нам лучший сериализатор.
Они лишь ограничивают группу сериализаторов, которые вам нужно использовать в качестве основы.
Вы будете использовать сериализатор для ВАШИХ данных.
Поэтому окончательное решение необходимо принимать после запуска тестов на ВАШИХ данных, особенно если эти данные сильно отличаются от тех, которые используются в наших тестах.
На что НЕ стоит обращать внимание:
- Если тесты несколько раз показывают разницу в цифрах, не стоит обращать внимание на разницу в процентах.
Это не только бессмысленно, но и неправильно.
Небольшие изменения в скорости или размерах можно легко исказить, слегка изменив тестовые данные.
Данные испытаний
Мы постарались представить данные по наиболее используемым приложениям.Статистики использования сериализаторов у нас нет, поэтому мы отбирали данные исходя из собственного опыта.
Если вы видите, что мы упустили что-то важное, сообщите нам об этом или просто добавьте свои тестовые данные в Serbench. Мы видим типичные применения в нескольких областях:
- распределенные, независимые системы .
Программы выполняются независимо, в разных процессах или на разных машинах и обмениваются данными.
Программы обмениваются только контрактами и интерфейсами.
К этому типу относятся системы обмена сообщениями .
- распределенные, но тесно связанные системы .
Отличие от предыдущего случая в том, что системы могут обмениваться не только контрактами, но и библиотеками.
Чаще всего эти связанные системы разрабатываются в одном месте.
К этому типу относятся ПКП (Удаленный вызов процедур).
- системы хранения .
Данные передаются между программами и хранилищами данных.
Отличие от предыдущих случаев в том, что цикл сериализации-десериализации не происходит в течение микросекунд или секунд. Данные могут храниться годами.
В течение периода хранения контракты данных часто меняются, что приводит к возникновению проблемы управления версиями данных.
Мы не тестировали сериализаторы на работу с версиями.
Любые из имеющихся тестовых данных могут работать с системами хранения.
Но сериализаторы, поддерживающие управление версиями данных, в этом случае могут оказаться более удобными.
Типичный человек
Вот простой класс без интерфейсов и наследования.
Практически все представленные сериализаторы проходят этот тест.
Телеметрия
Такие данные генерируются устройствами IoT (Интернета вещей).Их отличие – наличие числовой информации, отметок времени и нескольких идентификаторов.
Иногда данные очень короткие при отправке одного или нескольких номеров; Иногда пересылаются большие массивы чисел.
Структура данных проста.
Здесь важна скорость и плотность упаковки данных.
ЭОД
Данные EDI (электронный обмен данными) являются эквивалентом документов.Они характеризуются сложной иерархической структурой и вложенностью классов.
Есть коллекции классов.
Граф объектов
Если вы используете объектно-ориентированную разработку, вам, вероятно, приходилось иметь дело с такими классами.Для них характерны сложные взаимоотношения между классами.
Мы тестируем класс Conference, который имеет коллекцию Events. У мероприятия может быть несколько Участников (Участник) и несколько Тем (Тема конференции).
Что интересно, у участника может быть несколько отношений, каждый из которых ссылается на другого участника.
Результатом являются циклические соединения.
Это обычная ситуация, но оказывается, что очень немногие сериализаторы могут обрабатывать циклические отношения.
Пакетирование
Представьте себе ситуацию, когда вам нужно отправить сразу несколько экземпляров объектов.Это типичная ситуация в распределенных системах.
Объединив несколько фрагментов данных в один пакет, который передается по сети за один шаг, мы можем значительно ускорить передачу.
Пакет называется пакетным, отсюда и название пакетный.
Обычно нам необходимо явно создать пакет, заключая элементы данных в специальный класс конверта.
Некоторые сериализаторы позволяют обойтись без конвертов, что значительно упрощает разработку.
Процесс тестирования
Здесь все просто.За один цикл тестирования мы сериализуем объект или несколько объектов в случае пакета и немедленно десериализуем его обратно.
Конечный и исходный объекты сравниваются для устранения ошибок.
Сравнение производится быстро, только для некоторых значений.
Полное сравнение мы не делаем, но все интерфейсы для полного сравнения доступны.
Несколько циклов испытаний объединяются в один проход (прогон), в начале которого формируются данные испытаний.
Несколько тестов объединены в последовательности, первый тест из которых является разминочным.
Этот тест обычно состоит из одного цикла, целью которого является инициализация всех объектов, необходимых данному сериализатору.
Некоторые сериализаторы инициализируются быстро, но сериализуются медленно, некоторые — наоборот. Если вам нужно один раз воспользоваться сериализатором, то не стоит пренебрегать результатами прогревочных тестов, для вас они самые важные.
Обычно мы сначала тестировали один объект, а затем коллекцию объектов.
Как оказалось, сериализаторы можно оптимизировать для работы с коллекциями.
Тогда они смогут пройти путь от аутсайдеров до лидеров.
Любые данные, а обычно коллекции, могут быть очень большими, что может привести к резкому замедлению работы сериализатора или к ошибкам.
В некоторых неприятных случаях сериализатор просто крашил систему.
Результаты теста
Мы перечисляем победителей тестов только в сумме по всем тестам.Победители отдельных тестов очень хорошо представлены на страницах результатов тестов на Веб-сайт .
Здесь мы сделаем некоторые выводы.
Хочу обратить ваше внимание на то, что мы не претендуем на истину в последней инстанции, мы лишь комментируем цифры.
Цифры могут сильно измениться в будущих тестовых обновлениях.
Типичный человек
Результаты теста .Я рассмотрю этот тест подробно.
Остальные тесты являются базовыми.
Все тесты Почти все тесты выявили одни и те же быстрые сериализаторы: ProtoBuf, NFX Slim, MsgPack, NetSerializer. Прогревочные тесты дали очень широкий разброс скоростей.
Microsoft BinaryFormatter продемонстрировал хорошую упаковку коллекций и худшую упаковку одного объекта.
К сожалению, Json.Net не попал в топ ни в одном тесте.
Разминочные тесты Скорость Удивительный разброс скоростей.
NFX Slim выполняет тысячи операций, но, например, Jil выполняет только одну операцию в секунду.
Большинство сериализаторов выполняют от одного до двух десятков операций в секунду, а иногда и несколько десятков.
Что еще более удивительно, так это то, что NFX Slim зарабатывает около 45 тысяч! десериализаций в секунду.
Но по понятным причинам мы учитываем только самые медленные операции.
Упаковка Разброс не такой большой, как в скоростях.
Несколько победителей показывают почти одинаковые результаты, и сериализаторы JSON, естественно, показывают аналогичные результаты.
Мы специально сделали два теста для одного из сериализаторов JSON (NFX Json).
Один из тестов выдает текст JSON в красивом формате, со всеми отступами и переносами строк, а другой тест выдает JSON без форматирования.
Как видите, размеры для обоих случаев довольно сильно отличаются друг от друга.
Этот результат еще раз подтверждает известное правило: никогда не форматируйте сериализованные данные в канале! Используйте форматирование только для представления и никогда для передачи данных.
Пакетирование
Результаты теста .Только ProtoBuf, Microsoft BinaryFormatter и NFX Slim могут выполнять пакетную сериализацию.
При этом в Slim есть специальный режим пакетной обработки.
Здесь существует большая разница в скоростях для разных типов данных.
Победители варьируются от ProtoBuf для классов Trading и EDI до Slim для классов RPC и Personal. В то же время ProtoBuf не смог сериализовать класс RPC, в котором было обнаружено поле object[].
Можно резюмировать, что только Microsoft BinaryFormatter и NFX Slim успешно прошли этот тест. Microsoft BinaryFormatter, как всегда, показал отличные результаты в прогревочных тестах и стабильно худшие результаты в упаковке, что не умаляет того факта, что он работал без ошибок.
Граф объектов
Результаты теста .Этот тест оказался самым сложным для сериализации.
Многие сериализаторы его не прошли.
Многие прошли, но при этом показали ужасные скорости и упаковку.
Например, Джил на тесте ОбъектГрафик: Конференции: 1; Участники: 250; События: 10 упаковали данные в 2,6 МБ, а лидеры упаковали данные чуть более чем в 100 КБ, то есть потратили в 26 раз меньше памяти.
В этом тесте мы видим нескольких лидеров, которые выигрывают с очень большим отрывом.
Это ProtoBuf и NFX Slim. Microsoft BinaryFormatter неожиданно оказался среди этих лидеров с точки зрения упаковки.
ЭДИ Х12
Результаты теста .Что было интересно, так это то, что по мере роста объема данных все больше и больше сериализаторов оказывались с ошибками.
Как обычно, лидером в прогревочном тесте является NFX Slim. Похоже, лидеры упаковки: ProtoBuf, MsgPack, NetSerializer, NFX Slim — для таких случаев используют специальные методы упаковки и эти методы работают очень хорошо.
Обращу ваше внимание на то, что XML, который часто используется для сериализации и обработки EDI-документов, в виде XmlSerializer показал отвратительные результаты при упаковке, затрачивая в 8-9 раз больше места для сериализованных данных.
Выбор сериализатора
Почему нам нужно выбрать сериализатор? Почему мы не можем обойтись сериализаторами из .NET Framework? (Microsoft поставляет несколько сериализаторов, некоторые из них более поздние, например Bond и Avro.) Дело в том, что сериализаторы становятся все более важными элементами распределенных систем.
Медленный сериализатор может помешать вам достичь максимальной производительности; быстрый сериализатор может сделать вашу систему лучше, чем у конкурентов.
Новые сериализаторы для .
NET сейчас появляются с завидной регулярностью.
Каждый из них рекламируется как самый быстрый.
В качестве доказательства создатели предоставляют результаты испытаний.
Мы разработали собственную тест-систему и провели независимые исследования.
Теперь мы обсудим критерии, которые помогут вам сделать осознанный выбор сериализатора.
Критерии выбора основаны на результатах проведенных испытаний.
Надежность сериализации
Мы были удивлены, обнаружив, что многие сериализаторы не проходят базовые тесты.В лучшем случае мы получили ошибку в программе, в худшем — данные были потеряны без всякого предупреждения или Windows зависла на неопределенный срок.
В промежуточном случае объекты были искажены.
Пожалуйста, внимательно прочитайте результаты наших тестов.
Эти результаты во многом зависят от данных.
Если данные просты по структуре, то с этой задачей справится практически любой сериализатор.
Если данные сложные или большого размера, то, увы, все не так хорошо.
Я акцентирую внимание на надежности, потому что вряд ли скорость работы или плотность упаковки данных будут оправданием потери данных или зависания системы.
Конечно, самым надежным сериализатором является Microsoft БинарныйФорматтер .
Он не самый быстрый, но на это есть веская причина.
Он сериализует практически все без ошибок.
Вы сами выбираете формат данных?
Например, вы получаете данные от партнера в формате XML, и вам приходится работать с XML. У вас нет возможности изменить эту ситуацию.В этом случае ваш выбор ограничен XmlSerializer и Json.Net. Если вы интегрируете свою систему с чужими системами, выбор будет сделан за вами, и вам, скорее всего, придется использовать один из двух стандартных форматов: XML или JSON. В редких случаях вам понадобится работать с форматом CSV или конкретным системным форматом.
Чаще всего это происходит при интеграции с системами прошлого тысячелетия.
Если вам нужно сериализовать простые типы .
NET, такие как int, double, bool, то элементарной функции ToString() будет достаточно.
Сериализаторы, работающие с форматом JSON, более распространены.
JSON намного проще XML, что в большинстве случаев является преимуществом.
Многие сериализаторы упаковывают данные в собственный двоичный формат. Формат JSON обычно намного компактнее XML. Бинарные форматы обычно более компактны, чем JSON. Если вы можете выбрать свой собственный формат данных, двоичный, вероятно, будет лучшим выбором.
Но помните, что в этом случае вы должны использовать один и тот же сериализатор как для сериализации, так и для десериализации.
На данный момент все бинарные форматы уникальны, ни один из них не стандартизирован.
Плотность упаковки данных
Что важнее, скорость сериализации/десериализации или плотность упаковки данных? Размер сериализованных данных обычно более важен, чем скорость процесса сериализации-десериализации.Это связано с тем, что скорость процессора (скорость, определяющая сериализацию-десериализацию) намного выше скорости передачи данных в сети, что обычно напрямую связано с размером передаваемых данных.
Уменьшение размера данных на 10% может привести к ускорению передачи данных на 10%, но удвоение скорости сериализации-десериализации может привести только к ускорению на 1%.
Вы пытаетесь выжать из своей системы максимальную производительность? Или, может быть, для вас важнее продуктивность разработчика?
Посмотрите, например, на такие сериализаторы, как Bond, Thrift, Cap'n Proto. Вы не просто берете классы и сериализуете их.Вам нужно использовать специальный язык IDL и описать эти классы.
Обычно вам помогут утилиты, генерирующие описания классов из самих классов.
Но даже если они существуют, вам нужно понять этот язык и отвлечься от реальной разработки.
Другие сериализаторы, например, Стройный от NFX, от вас ничего не требуют. Вы просто сериализуете любые классы.
В промежуточных случаях сериализуемые классы должны быть украшены атрибутами.
Вероятно, вы знакомы с атрибутом [Serializable].
Это важно? Да, это может быть важно.
Особенно, когда ваши занятия нетривиальны по структуре.
Например, в нашей тестовой системе вы найдете тестовый класс EDI, состоящий из десятков вложенных классов и сотен полей.
Добавление атрибутов ко всем этим классам и полям было утомительной и трудоемкой работой.
Это также важно при сериализации классов из библиотеки, к коду которых у вас нет доступа .
Взять код и добавить к нему атрибуты нельзя, код недоступен.
Часто, чтобы обойти эту ситуацию, программисты используют так называемые DTO ( Объект передачи данных ).
Их использование чревато усложнением программы и снижением скорости разработки.
Вместо работы над бизнес-логикой вам придется писать код, не имеющий к ней никакого отношения.
Вы выбираете сериализатор и для сериализации, и для десериализации, или только для одной из этих операций?
Если ваша система является только принимающей или отправляющей стороной, то согласитесь, это отличается от случая, когда вы отвечаете за обе операции.
Есть ли у ваших данных коллекции?
Сериализаторы можно оптимизировать для работы с коллекциями объектов.Другие сериализаторы никак не разграничивают коллекции, поэтому покажут гораздо худшую скорость и упаковку.
Каков размер ваших данных?
Данные могут быть очень большими, что может привести к резкому замедлению работы сериализатора или ошибкам сериализации.Сериализатор может просто привести к сбою системы.
Большие данные в памяти могут повлиять на сбор мусора, что, в свою очередь, может привести к приостановке работы программ на длительные периоды времени.
Вам нужно сериализовать что-то очень необычное?
И здесь вам помогут сериализаторы, специализирующиеся именно на этой задаче.Например, сериализатор, работающий с выражениями Linq .
Вам нужна супер-супер-производительность?
Тогда лучшим вариантом будет написать собственный узкоспециализированный сериализатор.Если вы не хотите этого делать, то обратите внимание на дополнительные методы, используемые разными сериализаторами.
Например, пакетирование это отличный метод для увеличения скорости.
К сожалению, лишь немногие сериализаторы могут использовать его без дополнительного кодирования.
Параллельная сериализация также является хорошим методом достижения высоких скоростей.
Если вы им пользуетесь, важно ли это для вас? потокобезопасность сериализатор.
Теги: #сериализатор #сериализация #C++ #CLR #.
NET #benchmark #тестирование #.
NET #C++
-
Вася Как Компилятор
19 Oct, 24 -
Мфкаст №47. Много Новых Продуктов
19 Oct, 24 -
Белорусский Язык В Google Translate
19 Oct, 24 -
Firefox 2.0 И Ie7: Кто Ест Больше?
19 Oct, 24