JSON SAX parsing for chaotic #1058
Open
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
SAX-парсинг JSON в пользовательские типы
Этот PR добавляет возможность эффективного парсинга JSON напрямую в пользовательские структуры данных, минуя промежуточное DOM-представление, с использованием SAX-парсеров.
Парсинг через DOM
Прямой SAX-парсинг для контейнеров STL
Новый механизм использует
formats::json::FromStringAs<T>(), под капотом выбирает SAX-парсер для стандартных контейнеров. Он строит C++ объект "на лету", читая JSON-поток, что исключает создание и последующий обход DOM-дерева.Иерархическая валидация
Позволяет применять функции-валидаторы на любом уровне вложенности во время SAX-парсинга.
Для этого используется обертка
parser::WithValidators. Парсер будет применять указанные валидаторы к каждому элементу коллекции.Пример: Проверить, что каждый
intв векторе — положительный.Валидаторы для всего контейнера передаются как шаблонные аргументы в
FromStringAs. Можно применять несколько валидаторов к одному и тому же значению.Пример: Проверить, что вектор не пустой, и что каждый его элемент — положительное число.
SAX-парсинг для пользовательских типов
Для включения SAX-парсинга для пользовательской структуры, необходимо предоставить для нее метаданные. Это делается путем добавления статической функции DescribeForJsonParsing().
Это позволяет парсеру напрямую сопоставлять ключи JSON с членами C++ структуры, полностью избегая DOM. Такие структуры можно вкладывать друг в друга и в любые контейнеры STL.
Пример:
Система валидации без изменений работает и для пользовательских типов, позволяя проверять как каждый объект, так и весь контейнер.
Пример:
Система выбора парсера работает по следующему приоритету:
DescribeForJsonParsing()у типа. Если есть — используется ObjectParser (SAX).Parse(const json::Value&, To<T>). Если есть — используется старый, более медленный подход черезJsonValueProxyParser (DOM).static_assert, который выведет в консоль, подсвеченную инструкцию с примерами кода, объясняющую, как реализовать один из двух способов парсинга.Бенчмарки
Таблица:
StdContainer
std::vector<std::map<std::string, std::set<int>>>StdContainer/8StdContainer/16StdContainer/32StdContainer/64StdContainer/128StdContainer/256StdContainer/512UserType
std::vector<BenchObject>UserType/8UserType/16UserType/32UserType/64UserType/128UserType/256UserType/512Raw benchmarks data
Closes #987
Note: by creating a PR or an issue you automatically agree to the CLA. See CONTRIBUTING.md. Feel free to remove this note, the agreement holds.