Maximum sérialisé Protobuf de taille de message
Est-il un moyen pour obtenir la taille maximum d'un certain protobuf message une fois qu'il sera sérialisé?
Je fais référence à des messages qui ne contiennent pas de "répétée" éléments.
Remarque que je suis pas référence à la taille d'un protobuf message avec un contenu spécifique, mais à la maximum possible taille qu'il peut faire (dans le pire des cas).
OriginalL'auteur traveh | 2015-06-18
Vous devez vous connecter pour publier un commentaire.
En général, tout protobuf message peut être n'importe quelle longueur en raison de la possibilité de domaines inconnus. Si vous recevez un message, vous ne pouvez pas faire d'hypothèses sur la durée. Si vous êtes envoi un message que vous avez construit vous-même, alors vous pouvez peut-être supposer qu'il contient uniquement les champs que vous savez à propos de -- mais encore une fois, vous pouvez également calculer facilement le message exact de taille dans ce cas. Ainsi, il est généralement pas utile de se demander quelle est la taille maximale.
Avec cela dit, vous pouvez écrire du code qui utilise la
Descriptor
interfaces pour itérer sur lesFieldDescriptor
s pour un type de message (MyMessageType::descriptor()
).Voir: https://developers.google.com/protocol-buffers/docs/reference/cpp/google.protobuf.descriptor
Similaire existe des interfaces en Java, Python, et probablement d'autres.
Voici les règles à mettre en œuvre:
Chaque domaine est composé d'une balise de suivi de certaines données.
Pour le tag:
Pour les données:
bool
est toujours un octet.int32
,int64
,uint64
, etsint64
ont une longueur de données maximale de 10 octets (oui,int32
peut être de 10 octets s'il est négatif, malheureusement).sint32
etuint32
avoir un maximum de données longueur de 5 octets.fixed32
,sfixed32
, etfloat
sont toujours exactement 4 octets.fixet64
,sfixed64
, etdouble
sont toujours exactement 8 octets.Si votre message contient tout ce qui suit, alors que sa longueur maximale est illimitée:
string
oubytes
. (Sauf si vous savez de leur longueur max, dans ce cas, c'est que la longueur max plus un préfixe de longueur, comme avec les sous-messages.)[packed=true]
, dans ce cas, vous devrez rechercher les détails.)int32
peut prendre jusqu'à 10 octets si négatif ? Autant que je sache tout int32 codé à l'aide de varint peut être codé à l'aide d'un maximum de 5 octets.Oui j'en suis sûr, depuis que j'ai écrit le code. 🙂 Négatif int32s être rembourré à 10 octets parce que int32s devraient être avant-compatible avec int64s, de sorte que vous pouvez en modifier un existant int32 champ de int64 dans le futur si vous en avez besoin.
OriginalL'auteur Kenton Varda
Autant que je sache, il n'y a pas de fonction pour calculer la taille maximale de Google propre protobuf.
Nanopb générateur calcule la taille maximale lorsque cela est possible et les exportations comme un
#define
dans le fichier généré.Il est également très simple à calculer manuellement pour les petits messages, basé sur la protobuf encodage de la documentation.
OriginalL'auteur jpa
Tandis que la mise en œuvre de protobuffer 3 message le calcul de la taille, j'ai trouvé que la plupart de ce Kenton a dit est vrai. Je n'ai couru en un de la surveillance: les Tags sont créés à partir du numéro de champ, qui est à gauche d'un décalage de 3 bits, bit par bit par un ou binaire avec le type de fil (qui se trouve dans wire_format_lite.h). Ce résultat est ensuite codé comme un
var int
. Donc, pour les Balises qui sont un peu plus de 16, la balise sera 2 octets, mais si le numéro de champ est plus grande (>~1000), puis la balise sera de plus de 3 octets. Ce n'est probablement pas un problème pour protobuffer 3 utilisateurs, puisque le fait d'avoir un numéro de champ que les grands est une mauvaise utilisation de protobuf.OriginalL'auteur Smasher