Мы должны помнить о производительности при написании кода, избегая при этом нано-оптимизаций. Иногда то, что выглядит как скромная оптимизация, имеет огромное значение. Сегодня мы увидим, как System.Text.Json имеет ловушку снижения производительности.

Что не так с этим кодом?

Каждый раз, когда мы запускаем эту функцию, она создает новый JsonSerializerOptions. Насколько плохо каждый раз создавать экземпляр нового объекта? Как правило, создание нового объекта каждый раз незначительно с точки зрения производительности и распределения памяти. Тем не менее, выполняя профилирование производительности, моя команда получила подозрительные результаты. Время, затраченное на эти функции, было равно:

  • ОтправитьToServiceBus()
  • Сериализация()

Это вызывает опасения: во-первых, это сериализация данных, для которых наши пакеты хорошо оптимизированы, а во-вторых, передача данных по сети, где ожидается задержка.

Почему сериализация такая медленная?

Новый System.Text.Json использует ссылку экземпляра JsonSerializerOptions для кэширования метаданных сериализации, поэтому, если вы предоставляете новый экземпляр каждый раз, вы теряете кэширование, и код должен выполнять дорогостоящую операцию создания метаданных для каждой функции. вызов.

Проблема настолько распространена, что Microsoft даже посвятила ей целую страницу.

Пример

Документы предоставляют этот эталонный пример:

Как вы можете видеть из документов, разница огромна, более чем в 200 раз дороже. И ничто не скажет вам об этом, ни исключения, ни предупреждения. Единственный способ найти это — во время нагрузочного тестирования и профилирования. Это заставляет меня задаться вопросом, должно ли это быть предупреждением, поэтому мы уменьшаем количество раз, когда эта ошибка будет сделана.

Заключение

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

Помните, что создание параметров сериализатора каждый раз имеет серьезные последствия, поскольку инфраструктура кэширует внутренние метаданные по ссылке SerializerOptions.

Если вы видите новый JsonSerializerOptions(), убедитесь, что он относится к шаблону Singleton.

Удачного кодирования.