С++ - формат данных protobuf против rapidjson

используя RapidJSON, я могу хранить данные любого типа (поддерживаемые RapidJSON) в качестве значения по ключу. Могу ли я сделать это в protobuf? Если да, то как?

Причина, по которой я выбрал protobuf вместо rapidJSON, заключается в его скорости (а сравнение ключей в rapidJSON на самом деле является "строковым" сравнением, которое дорого обходится). Или есть какая-то альтернатива этому? может плоские буфера?

Требование - хранить данные любого типа по ключу типа int. Более быстрая сериализация/десериализация, чем обычный json.

Ищем ответы с точки зрения C++.


person helix    schedule 20.06.2017    source источник


Ответы (2)


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

Удобство и производительность API-интерфейса расширений зависит от реализации, но он должен прекрасно использоваться в официальном API-интерфейсе C++.

Ключевым моментом в расширениях является то, что их должен понимать только потребитель.

person Marc Gravell    schedule 20.06.2017

И Protobuf, и FlatBuffer имеют функцию словаря (см. https://developers.google.com/protocol-buffers/docs/proto#maps и https://google.github.io/flatbuffers/md__cpp_usage.html в разделе словари). Большая проблема, которая может возникнуть с обоими, заключается в том, что неудобно, чтобы значение было произвольным значением, поскольку оба определяются схемой, а это означает, что вам нужно указать фактический тип для значения. Вы можете обойти это, определив объединения всех возможных типов, но это не так удобно, как JSON.

Однако FlatBuffers имеет специальный формат для хранения любого значения без схемы: https://google.github.io/flatbuffers/flexbuffers.html. Это намного быстрее, чем JSON, более компактно и использует меньше дополнительной памяти для чтения (нет).

FlatBuffers имеет возможность использовать int в качестве ключа, но FlexBuffers пока этого не делает, поэтому вы можете рассмотреть возможность хранения FlexBuffer как значения внутри словаря FlatBuffer int.

Оба формата анализируют JSON и выводят в JSON, даже если они вложены.

FlexBuffers нельзя изменить на месте. FlatBuffers может, используя свой объектный API. Итак, снова вложение может работать хорошо, если вы можете повторно генерировать все значение FlexBuffer при его изменении.

Последняя альтернатива, о которой стоит упомянуть, — это std::map<int, std::vector<uint8_t>> (или unordered_map) для непосредственного хранения карты FlexBuffers. Это проще, но теперь проблема в том, что у вас нет удобного способа хранить все это.

person Aardappel    schedule 20.06.2017