Почему protobuf включает тип данных в сериализованные данные? - PullRequest
1 голос
/ 28 апреля 2020

Protobuf включает тип данных в сериализованные данные (Thrift делает это тоже). Однако приложение, считывающее данные, должно иметь возможность получать эту информацию из схемы.

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

Кроме того, исключение типа данных в сериализации может в определенной степени сэкономить пространство без ущерба для производительности во время выполнения. Есть мысли?

1 Ответ

1 голос
/ 28 апреля 2020

Protobuf включает тип данных в сериализованные данные

Обычно это не так. Это происходит только в том случае, если вы используете тип Any (когда он должен знать, какой message вы сохранили) или используете библиотеку с некоторой нестандартной поддержкой метаданных типа. Он абсолютно ничего не хранит о типе - только номера полей и типы проводов. Я подозреваю, что вы неправильно поняли что-то о данных, которые вы просматриваете.


Если вы имеете в виду тип провода; ему нужно, чтобы иметь возможность пропускать (или дословно хранить, для кругового обращения) поля, о которых он не знает (вещи, которые были не в схеме он был сгенерирован из). Тип проводника не достаточно информации для понимания содержимого поля - он очень неоднозначен без схемы - например, «длина с префиксом» может представлять как минимум 4 различных типа данных. В конечном итоге это 3 бита и упаковывается вместе с номером поля; Большую часть времени (ну, четыре-седьмые, включая поля 1-15) он даже не стоит лишнего байта.

Чтобы представить это в перспективе, в xml, правила поиска конца текущего значения будет:

  • , если это атрибут, ищите закрывающий "
  • , если это элемент, ищите закрывающий </theElementName> (принимая учитывает любое вложение)

Тип провода здесь определяет то же самое:

  • для varint: считывание до (и включая) следующего байта (максимум 10 ожидаемых ) который не имеет старшего бита, установленного
  • для 64-разрядных: считайте 8 байтов
  • для 32-разрядных: прочитайте 4 байта
  • для разделенной длины: прочитайте a varint, затем прочитайте столько байтов
  • для начальной группы: прочитайте в соответствующую конечную группу (принимая во внимание любую вложенность)

Так что это все о том, чтобы сказать, когда остановитесь , если вы уже не можете этого знать, потому что не ожидали этого поля.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...