cpp-ru / ideas

Идеи по улучшению языка C++ для обсуждения
https://cpp-ru.github.io/proposals
Creative Commons Zero v1.0 Universal
90 stars 0 forks source link

Json, XML, Ini format parser #430

Open apolukhin opened 3 years ago

apolukhin commented 3 years ago

Перенос предложения: голоса +10, -2 Автор идеи: ??

В С++ добавляется столько много вещей, это приятно.

Но в другой сторону, это печально, что С++ нет стаднтрный инструмент для работы с JSON, XML, INI форматом, который используется почти для все программы с сетевом содействием и других местах. Да, здесь очень много сторонных библиотеках, но у всех есть свои плюси и минусы и главное не в духе современный язык С++.

Недавно читал, С++20 добавили std::format -- очень круто! Python стил форматирование, не-такой громоздкой, быстрый как printf, легко расширяется с пользовательский тип данных, возмнож возвращает std::string, или возможно записывает результат на char [] массив.

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

apolukhin commented 3 years ago

yndx-antoshkka, 11 марта 2019, 16:17

Можно и добавить. Нужен работающий прототип.

Удалённый пользователь, 19 марта 2019, 21:47

Здесь несколько кандидат пришло в мою голову ( из http://json.org/ ) .

1) nlohman json https://github.com/nlohmann/json 2) rapidjson https://github.com/Tencent/rapidjson 3) jsoncpp https://github.com/open-source-parsers/jsoncpp

Но у них каждого есть минусы, например (1) nlohman громоздкий - более 15 тысяч строк исходный код и медленный, но использует более современный C++.

(2) rapidjson -- быстрый , но всегда придётся тащить за сабой аллокатор - очень не удобный.

(3) jsoncpp -- стабильный, но требует много ресурс.

Было бы здорово если найти как нибудь средный баланс между быстрота и удобности, и добавить эту.

И я удивляюсь, а почему в boost ( boost.org ) библиотекам никто не предлагает добавить json или XML формат парсери?

я в курсе там есть property_tree - - но это далеко от стандарта, нет там чисел, везде строка, нет массив, и очень медленный, еще бросает исключение когда парсирует, еще требует basic_stream , нет способ парсит обычная строка ( может я ошибаюсь).

ValentiWorkLearning commented 3 years ago

@apolukhin https://www.boost.org/doc/libs/1_75_0/libs/json/doc/html/index.html Мне почему-то кажется, что в boost уже завезли библиотеку для работы с json. Когда-то давно еще был json-spirit, но он outdated давно. А в 1.75, похоже, завезли что-то новое.

apolukhin commented 3 years ago

Boost.JSON выглядит многообещающе. Несколько смущает непривычная для Standard Library работа с аллокаторами и самописный string. Давайте я спрошу у авторов, планируют ли они её стандартизировать

incoder1 commented 3 years ago

Подавляющее большинство парсеров используют пул строк, в форматах вроде XML и JSON часто встречаются повторяющиеся строки скажем:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
   <soapenv:Header>
   </soapenv:Header>
</soapenv:Envelope>

или

{
administrator:[ 
 {
  "userName": "John Doe",
  "userRole": "admin"
 },
 {
  "userName": "John Doe",
  "userRole": "admin"
 }],
users: [ 
 {
  "userName": "John Doe",
  "userRole": "user"
 },
 {
  "userName": "John Doe",
  "userRole": "user"
 }],

Используется часто повторяющийся префикс soapenv и название тегов, аналогично название полей в json и enum значения типа userRole и т.д.. Если помещать copy on write строки в хеш таблицу, можно сократить потребление памяти и ускорить парсинг, причем существенно. К таким срокам можно так же применить и small string optimization если нужно. Второй важный момент - UNICODE в особенности UTF-8, который в std::basic_string не завезли. Поэтому парсеро-писатели с давних времен (expat, xerces, pugi.xml, json-c и т.д.) пишут велосипедные строки вместо универсального std::basic_string. В тех парсерах, где авторы не профилировали то что получается, std::basic_string делает производительности очень плохо, а потреблению памяти еще хуже. Все конечно зависит от реализации в стандартной библиотеке, однако она тоже разной бывает в зависимости от компилятора и платформы.

Стандартные распределители памяти тоже часто показывают не удовлетворительный результат, для парсеров больше подходят SLAB и stack подобные распределители, private heap-пы, анклавы и тому подобные механизмы. Парсеры в виду своей специфики часто выделяют объекты в памяти переменных размеров - сроки, ноды деревьев и т.п. Часто такие объекты нужно размещать в памяти по возможности ближе друг к другу, для достижения большей производительности и минимизации кеш промахов при обращении к памяти.

Суммируя - вполне возможно функциональность парсеров вообще не стоит стандартизировать. Потому как на вкус и цвет как известно, все может сильно зависеть как от потребностей программы так и от предпочтений программиста. Рано или поздно появятся альтернативные реализации и API. Если взять Java в стандарную библиотеку только для XML ввели : DOM, SAX и StAX. Для JSON уже ничего не вводили, но никто и не жалуется все пользуются тем что им больше нравится или подходит.