Quelqu'un qui a de l'expérience avec ces bibliothèques a-t-il des commentaires sur celle qu'elle préfère? Y a-t-il eu des différences de performances ou des difficultés d'utilisation?
J'ai un peu joué avec les deux systèmes, rien de grave, juste quelques trucs simples, mais j'ai senti qu'il y avait une réelle différence dans la manière dont vous êtes censé utiliser les bibliothèques.
Avec boost :: serialization, vous écrivez d’abord vos propres structures/classes, puis vous ajoutez les méthodes d’archivage, mais il vous reste encore quelques jolies classes "minces", qui peuvent être utilisées en tant que membres de données, héritées, peu importe.
Avec les tampons de protocole, la quantité de code généré, même pour une structure simple, est assez substantielle, et les structures et le code générés sont plus destinés à être utilisés, et vous utilisez la fonctionnalité des tampons de protocole pour transporter des données de et vers vos propres structures internes. .
J'utilise la sérialisation Boost depuis longtemps et je viens juste de creuser dans des tampons de protocole, et je pense qu'ils n'ont pas exactement le même objectif. BS (qui n'a pas vu cela venir) enregistre vos objets C++ dans un flux, alors que PB est un format d'échange que vous lisez vers/depuis.
Le modèle de données de PB est beaucoup plus simple: vous obtenez toutes sortes d’intégrations et de flottants, de chaînes, de tableaux, de structures de base et c’est à peu près tout. BS vous permet de sauvegarder directement tous vos objets en une seule étape.
Cela signifie qu'avec BS, vous obtenez plus de données sur le réseau mais vous n'avez pas à reconstruire toute la structure de vos objets, alors que les tampons de protocole sont plus compacts, mais qu'il reste encore du travail à faire après la lecture de l'archive. Comme son nom l'indique, l'un concerne les protocoles (transmission de données efficace en termes d'espace et agnostique sur la langue), l'autre la sérialisation (sauvegarde des objets à mémoire de forme).
Alors, qu'est-ce qui est le plus important pour vous: efficacité de la vitesse/espace ou code propre?
Il y a quelques problèmes supplémentaires avec boost.serialization que je vais ajouter au mélange. Mise en garde: Je n'ai aucune expérience directe avec les tampons de protocole au-delà de l'écrémage des documents.
Notez que même si je pense que boost et boost.serialization sont excellents, je suis parvenu à la conclusion que les formats d'archivage par défaut fournis ne constituent pas un excellent choix pour un format filaire.
Il est important de distinguer les versions de de votre classe (comme indiqué dans d’autres réponses, boost.serialization prend en charge le contrôle de version des données) et la compatibilité entre les différentes versions de bibliothèque de sérialisation .
Nouvelles versions de boost.serialization ne peut pas générer d'archives que des versions plus anciennes peuvent désérialiser . (l'inverse n'est pas vrai: nouvelles versions sont toujours destinés à désérialiser les archives créées par des versions antérieures). Cela a conduit aux problèmes suivants pour nous:
Google semble réellement publier le format filaire des tampons de protocole , et Wikipedia les décrit comme compatible avec la version antérieure, compatible avec la version antérieure (bien que je pense que Wikipedia parle de versioning des données plutôt que du protocole versioning de la bibliothèque de tampons). Bien qu’aucune de celles-ci ne soit une garantie de compatibilité en aval, cela me semble une indication plus forte.
En résumé, , je préférerais un format de câble bien connu et publié comme les tampons de protocole lorsque je n'ai pas la possibilité de mettre à niveau le client et le serveur en mode bloqué. .
Note de bas de page: fiche éhontée pour un réponse connexe par moi.
Sérialisation Boost
Tampons de protocole
La sérialisation Boost est une bibliothèque permettant de convertir un objet en un flux de données sérialisé. Les tampons de protocole font la même chose, mais font également un autre travail pour vous (comme la gestion de version et l'échange). La sérialisation Boost est plus simple pour les "petites tâches simples". Les tampons de protocole sont probablement meilleurs pour une "infrastructure plus grande".
EDIT: 24-11-10: Ajouté "automatiquement" à la gestion des versions de BS.
Je n'ai aucune expérience de la sérialisation boost, mais j'ai utilisé des tampons de protocole. J'aime beaucoup les tampons de protocole. Gardez ceci à l'esprit (je le dis avec aucune connaissance de boost).
J'espère que cela t'aides.
boost.serialization a juste besoin du compilateur C++ et vous donne un peu de sucre syntaxique comme
serialize_obj >> archive;
// ...
unserialize_obj << archive;
pour sauvegarder et charger. Si C++ est le seul langage que vous utilisez, vous devriez donner un sérieux coup de pouce à boost.serialization.
J'ai jeté un coup d'oeil rapide aux tampons de protocole de Google. D'après ce que je vois, je dirais que ce n'est pas directement comparable à boost.serialization. Vous devez ajouter un compilateur pour les fichiers .proto à votre chaîne d'outils et gérer les fichiers .proto eux-mêmes. L'API ne s'intègre pas dans C++, contrairement à boost.serialization.
boost.serialization fait très bien son travail: sérialiser des objets C++:.
Comme je n’ai jusqu’à présent utilisé que boost.serialization, je ne peux pas commenter la comparaison des performances.
Correction à la précédente (supposez que c'est cette réponse ) à propos de la sérialisation Boost:
Cela permet de supporter le versioning des données .
Si vous avez besoin de compression, utilisez un flux compressé.
Peut gérer les échanges finaux entre plates-formes car le codage peut être texte, binaire ou XML.
Je n'ai jamais implémenté quoi que ce soit en utilisant la bibliothèque de boost, mais j'ai trouvé le protobuff de Google plus réfléchi, et le code est beaucoup plus propre et plus facile à lire. Je suggérerais de jeter un coup d'œil sur les différentes langues avec lesquelles vous voulez l'utiliser, de lire le code et la documentation, puis de vous décider.
La seule difficulté que je rencontrais avec les protobufs a été de nommer une fonction très utilisée dans leur code généré GetMessage (), ce qui bien sûr est en conflit avec la macro Win32 GetMessage.
Je recommanderais toujours fortement les protobufs. Ils sont très utiles.
Comme dans presque tous les domaines de l'ingénierie, ma réponse est… "ça dépend."
Les deux technologies sont bien testées et validées. Les deux vont prendre vos données et les transformer en quelque chose de convivial pour envoyer quelque part. Les deux seront probablement assez rapides, et si vous comptez vraiment un octet ici ou là, vous ne serez probablement pas satisfait non plus (les deux paquets créés ne seront en réalité qu'une petite fraction de XML ou JSON).
Pour moi, tout dépend du flux de travail et de la question de savoir si vous avez besoin d'autre chose que de C++ à l'autre bout.
Si vous voulez d'abord comprendre le contenu de votre message et que vous construisez un système à partir de rien, utilisez des tampons de protocole. Vous pouvez concevoir le message de manière abstraite, puis générer automatiquement le code dans la langue de votre choix (des plugins tiers sont disponibles pour à peu près tout). De plus, je trouve la collaboration simplifiée avec les tampons de protocole. Je viens d’envoyer un fichier .proto et l’autre équipe a une idée précise des données transférées. Je ne leur impose rien non plus. S'ils veulent utiliser Java, allez-y!
Si j'ai déjà construit une classe en C++ (et cela s'est passé plus souvent qu'autrement) et que je souhaite maintenant envoyer ces données sur le réseau, la sérialisation Boost a évidemment beaucoup de sens (en particulier lorsque j'ai déjà une dépendance Boost ailleurs ).
Je sais que c'est une question plus ancienne maintenant, mais je pensais jeter mon 2 pence dedans!
Avec boost, vous aurez l’occasion d’écrire des validations de données dans vos cours; c’est bien parce que la définition des données et les contrôles de validité sont tous au même endroit.
Avec GPB, le mieux que vous puissiez faire est de mettre des commentaires dans le fichier .proto et d’espérer que ceux qui l’utiliseront le liront, y prêteront attention et mettront en œuvre les contrôles de validité eux-mêmes.
Inutile de dire que cela est peu probable et peu fiable si vous vous fiez à quelqu'un d'autre à l'autre bout du flux réseau pour le faire avec la même vigueur que vous-même. De plus, si les contraintes sur la validité changent, plusieurs modifications du code doivent être planifiées, coordonnées et effectuées.
Par conséquent, je considère que GPB est inapproprié pour les développements dans lesquels il est difficile de rencontrer et de discuter régulièrement avec tous les membres de l'équipe.
== EDIT ==
Le genre de chose que je veux dire est la suivante:
message Foo
{
int32 bearing = 1;
}
Maintenant, qui peut dire quelle est la plage valide de bearing
? Nous pouvons avoir
message Foo
{
int32 bearing = 1; // Valid between 0 and 359
}
Mais cela dépend de la lecture et de l'écriture du code par quelqu'un d'autre. Par exemple, si vous le modifiez et que la contrainte devient:
message Foo
{
int32 bearing = 1; // Valid between -180 and +180
}
vous êtes complètement dépendant de tous ceux qui ont utilisé ce fichier .proto pour mettre à jour leur code. C'est peu fiable et coûteux.
Au moins, avec la sérialisation Boost, vous distribuez une seule classe C++ et vous pouvez intégrer des contrôles de validité des données. Si ces contraintes changent, personne d'autre n'est obligé de faire autre chose que de s'assurer qu'il utilise la même version du code source que vous.
Alternative
Il existe une alternative: ASN.1. C'est ancien, mais il y a des choses vraiment très utiles:
Foo ::= SEQUENCE
{
bearing INTEGER (0..359)
}
Notez la contrainte. Ainsi, chaque fois que quelqu'un consomme ce fichier .asn, génère du code, il se retrouve avec un code qui vérifie automatiquement que bearing
est compris entre 0 et 359. Si vous mettez à jour le fichier .asn,
Foo ::= SEQUENCE
{
bearing INTEGER (-180..180)
}
tout ce qu'ils doivent faire est de recompiler. Aucun autre changement de code n'est requis.
Vous pouvez aussi faire:
bearingMin INTEGER ::= 0
bearingMax INTEGER ::= 360
Foo ::= SEQUENCE
{
bearing INTEGER (bearingMin..<bearingMax)
}
Notez le <
. De plus, dans la plupart des outils, bearingMin et bearingMax peuvent apparaître en tant que constantes dans le code généré. C'est extrêmement utile.
Les contraintes peuvent être assez complexes:
Garr ::= INTEGER (0..10 | 25..32)
Regardez le chapitre 13 dans ce PDF ; C'est incroyable ce que vous pouvez faire.
Les tableaux peuvent aussi être contraints:
Bar ::= SEQUENCE (SIZE(1..5)) OF Foo
Sna ::= SEQUENCE (SIZE(5)) OF Foo
Fee ::= SEQUENCE
{
boo SEQUENCE (SIZE(1..<6)) OF INTEGER (-180<..<180)
}
ASN.1 est démodé, mais reste activement développé, largement utilisé (votre téléphone mobile l’utilise beaucoup) et beaucoup plus flexible que la plupart des autres technologies de sérialisation. La seule lacune que je puisse constater est qu’il n’ya pas de générateur de code décent pour Python. Si vous utilisez C/C++, C #, Java, ADA, vous serez bien servi par une combinaison d'outils gratuits (C/C++, ADA) et commerciaux (C/C++, C #, Java).
J'aime particulièrement le large choix de formats filaires binaires et textuels. Cela le rend extrêmement pratique dans certains projets. La liste des formats de fil comprend actuellement:
0
et 15
ne prendra que 4 bits
sur le réseau) plus d'autres.
Notez les deux derniers? Oui, vous pouvez définir des structures de données dans ASN.1, générer du code et émettre/consommer des messages au format XML et JSON. Pas mal pour une technologie qui a débuté dans les années 1980.
Le versionnage est effectué différemment de GPB. Vous pouvez autoriser des extensions:
Foo ::= SEQUENCE
{
bearing INTEGER (-180..180),
...
}
Cela signifie qu’à une date ultérieure, je pourrai ajouter Foo
et que les anciens systèmes dotés de cette version pourront toujours fonctionner (mais ne pourront accéder qu’au champ bearing
).
Je note très haut ASN.1. Cela peut être difficile à gérer (les outils peuvent coûter de l’argent, le code généré n’est pas forcément beau, etc.). Mais les contraintes sont une caractéristique vraiment fantastique qui m’a épargné maintes fois mal au cœur. Les développeurs ont beaucoup de peine à se plaindre lorsque les encodeurs/décodeurs signalent qu'ils ont généré des données duff.
Autres liens:
Observations
Pour partager des données:
Pour être honnête, si GPB ajoutait un mécanisme de contraintes, il serait gagnant. XSD est proche mais les outils sont presque universellement nuls. S'il y avait des générateurs de code convenables d'autres langages, le schéma JSON serait plutôt bon.
Si GPB avait des contraintes ajoutées (note: cela ne changerait aucun des formats wire), ce serait celui que je recommanderais à tout le monde pour presque tous les buts. Bien que l'uPER d'ASN.1 soit très utile pour les liaisons radio.
If GPB had constraints added (note: this would not change any of the wire formats), that'd be the one I'd recommend to everyone for almost every purpose. Though ASN.1's uPER is very useful for radio links.
Vous pouvez utiliser la sérialisation boost en association étroite avec vos objets de domaine "réels" et sérialiser la hiérarchie complète des objets (héritage). Protobuf ne supporte pas l'héritage, vous devrez donc utiliser l'agrégation. Les gens avancent que Protobuf devrait être utilisé pour les objets de transfert de données (DTO) et non pour les objets de domaine principaux eux-mêmes. J'ai utilisé à la fois boost :: serialization et protobuf. La performance de boost :: sérialisation doit être prise en compte, céréales pourrait être une alternative.