Domanda

Qualcuno con esperienza con queste librerie ha qualche commento su quale ha preferito?Ci sono state differenze prestazionali o difficoltà nell'utilizzo?

È stato utile?

Soluzione

Ho giocato in giro un po 'con entrambi i sistemi, nulla di grave, solo qualche semplice roba hackish, ma ho sentito che c'è una vera differenza nel modo in cui si suppone di utilizzare le librerie.

Con boost :: serializzazione, si scrive il proprio struct / classi prima, e poi aggiungere i metodi di archiviazione, ma si sta ancora a sinistra con alcune classi piuttosto "slim", che può essere utilizzato come membri di dati, ereditato, qualunque .

Con i buffer di protocollo, la quantità di codice generato anche per una struttura semplice è abbastanza sostanziale, e le strutture e il codice che viene generato è di più significava per operare su, e di utilizzare funzionalità di buffer di protocollo per il trasporto di dati da e verso il vostro proprie strutture interne.

Altri suggerimenti

Sto usando Boost serializzazione per lungo tempo e solo scavato nel buffer di protocollo, e penso che non hanno lo stesso scopo esatto. BS (non ha visto che a venire) salva il C ++ gli oggetti in un flusso, mentre il PB è un formato di interscambio di leggere da /.

datamodel di PB è il modo più semplice: si ottengono tutti i tipi di interi e galleggianti, stringhe, array, struttura di base e che è praticamente. BS consente di salvare direttamente tutti gli oggetti in un solo passaggio.

Ciò significa che con BS ottenere più dati sul filo, ma non c'è bisogno di ricostruire tutta la vostra struttura di oggetti, mentre i buffer di protocollo è più compatta, ma c'è più lavoro da fare dopo aver letto l'archivio. Come dice il nome, una è per i protocolli (indipendente dal linguaggio, lo spazio efficiente dei dati di passaggio), l'altro è per la serializzazione (salvataggio di oggetti non-sforzo).

Quindi, ciò che è più importante per voi:? Velocità / efficienza dello spazio o il codice pulito

Ci sono un paio di problemi aggiuntivi con boost.serialization che dovrò aggiungere al mix. Caveat:. Non ho alcuna esperienza diretta con i buffer di protocollo al di là sfiorando i documenti

Si noti che mentre penso spinta, e boost.serialization, è grande in quello che fa, sono giunto alla conclusione che i formati di archivio di default si tratta con non sono la scelta ideale per un formato di filo.

E 'importante distinguere tra le versioni di la classe (come detto in altre risposte, boost.serialization ha qualche supporto per il controllo delle versioni dei dati) e la compatibilità tra le diverse versioni del biblioteca serializzazione .

Le nuove versioni di boost.serialization non può generare archivi che le versioni più vecchie possono deserializzare (il contrario non è vero: le versioni più recenti sono sempre destinati a deserializzare gli archivi realizzati da versioni precedenti).. Questo ha portato ai seguenti problemi per noi:

  • Sia il nostro client e server software creano oggetti serializzati che le altre consuma, in modo che possiamo muovere solo ad un boost.serialization più recente se aggiorniamo sia client che server in sincronia. (Questa è una grande sfida in un ambiente dove non si ha il pieno controllo dei vostri clienti).
  • Boost viene fornito come una grande libreria con parti condivise, e sia il codice di serializzazione e le altre parti della libreria Boost (per esempio shared_ptr) potrebbe essere in uso nello stesso file, non posso aggiornare qualsiasi parti di spinta perché non posso aggiornare boost.serialization. Non sono sicuro se è possibile / sicura / sane per tentare di collegare più versioni di spinta in un unico file eseguibile, o se ci sono il bilancio / energia per il refactoring fuori pezzi che hanno bisogno di rimanere in una versione precedente di spinta in un separato eseguibile (DLL nel nostro caso).
  • La vecchia versione di spinta siamo bloccati sulla non supporta l'ultima versione del compilatore che usiamo, così siamo bloccati su una vecchia versione del compilatore troppo.

Google sembra in realtà pubblicare il formato di buffer di protocollo filo , e Wikipedia li descrive come , retro-compatibile compatibile in avanti (anche se credo che Wikipedia si riferisce controllo delle versioni dei dati piuttosto che il protocollo di buffer biblioteca delle versioni). Mentre nessuna di queste è una garanzia di avanti-compatibilità, sembra un'indicazione forte per me.

In sintesi, io preferirei un ben noto, filo formato pubblicato come buffer di protocollo quando non ho la possibilità di aggiornamento del client e del server in sincronia.

Nota:. Spudorato per una risposta da me

Boost serializzazione

  • è una libreria per la scrittura dei dati in un flusso.
  • non comprimere i dati.
  • non supporta i dati di versioning automatico.
  • supporta contenitori STL.
  • proprietà dei dati scritti dipendono flussi scelti (ad es endian, compresso).

protocollo buffer

  • genera codice da descrizione dell'interfaccia (supporta C ++, Python e Java per default. C, C # e altri da 3a parte).
  • opzionalmente comprime i dati.
  • gestisce il versioning automatico dei dati.
  • gestisce lo scambio endian tra le piattaforme.
  • non supporta contenitori STL.

Boost serializzazione è una libreria per la conversione di un oggetto in un flusso serializzato di dati. Buffer Protocollo fanno la stessa cosa, ma anche fare altri lavori per voi (come il controllo delle versioni e lo scambio endian). Boost serializzazione è più semplice per i "piccoli compiti semplici". I buffer di protocollo sono probabilmente meglio per "infrastrutture più grande".

EDIT: 24-11-10: Aggiunto "automaticamente" a BS versioning

.

Non ho esperienza con boost serializzazione, ma ho usato i buffer di protocollo. Mi piace il protocollo buffer molto. Tenere presente quanto segue (lo dico con nessuna conoscenza di spinta).

  • buffer di protocollo sono molto efficienti in modo da non immagino che essere un problema serio contro spinta.
  • buffer protocollo forniscono una rappresentazione intermedia che funziona con altri linguaggi (Python e Java ... e molto altro nelle opere). Se sai che stai solo utilizzando C ++, forse amplificare è meglio, ma la possibilità di utilizzare altre lingue è bello.
  • buffer di protocollo sono più come contenitori di dati ... non c'è nave oggetto orientato, come l'ereditarietà. Pensare alla struttura di ciò che si desidera serializzare.
  • buffer di protocollo sono flessibili perché è possibile aggiungere campi "facoltativi". Ciò significa è possibile modificare la struttura del buffer del protocollo senza rompere la compatibilità.

Spero che questo aiuti.

boost.serialization bisogno solo il compilatore C ++ e ti dà un po 'di zucchero sintassi come

serialize_obj >> archive;
// ...
unserialize_obj << archive;

per il risparmio e il caricamento. Se C ++ è l'unica lingua che si usa si dovrebbe dare boost.serialization un colpo serio.

Ho dato un'occhiata veloce al google buffer di protocollo. Da quello che vedo direi la sua non direttamente comparabili con boost.serialization. È necessario aggiungere un compilatore per i file Proto alla vostra toolchain e mantenere i file Proto stesso. L'API non si integra nel C ++ come boost.serialization fa.

boost.serialization fa il lavoro suo stato progettato per molto bene: di serializzare gli oggetti C ++ :) OTOH una query-API come Google buffer di protocollo che si è dà maggiore flessibilità.

Da quando ho usato solo boost.serialization finora non posso commentare sul confronto delle prestazioni.

Correzione sopra (immagino che questo è che rispondono ) su Boost serializzazione:

se non è permessa supporto dati versioni .

Se avete bisogno di compressione -. Utilizzare un flusso compresso

In grado di gestire lo scambio endian tra le piattaforme per la codifica può essere di testo, binario o XML.

Non ho mai implementato nulla utilizzando la libreria di spinta, ma ho trovato di Google protobuff ad essere più pensiero-out, e il codice è molto più pulito e più facile da leggere. Vorrei suggerire di dare un'occhiata alle varie lingue che si desidera utilizzare con e hanno un letto attraverso il codice e la documentazione e rendere la vostra mente.

L'unica difficoltà che ho avuto con protobufs stato hanno chiamato una funzione molto comunemente usato nella loro GetMessage codice generato (), che dei conflitti corso affronta la macro Win32 GetMessage.

io consiglierei comunque altamente protobufs. Sono molto utili.

Come per quasi tutto in ingegneria, la mia risposta è ... "dipende".

Entrambi sono ben testati, tecnologie controllati. Entrambi saranno prendere i dati e trasformarlo in qualcosa di amichevole per l'invio di un posto. Entrambi saranno probabilmente abbastanza veloce, e se siete veramente contando un byte qui o là, probabilmente non state andando a essere felice con entrambi (diciamocelo entrambi i pacchetti creati saranno una piccola frazione di XML o JSON).

Per quanto mi riguarda, si tratta veramente basso per il flusso di lavoro e se non avete bisogno di qualcosa di diverso da C ++ su l'altra estremità.

Se si vuole capire il contenuto del primo messaggio e si sta costruendo un sistema da zero, utilizzare il protocollo buffer. Si può pensare al messaggio in modo astratto e quindi generare automaticamente il codice in qualsiasi lingua desiderata (3rd plugin parti sono disponibili per quasi tutto). Inoltre, trovo la collaborazione semplificata con buffer protocollo. Ho appena inviare più di un file Proto e poi l'altra squadra ha una chiara idea di ciò che i dati vengono trasferiti. Anche io non impongo nulla su di loro. Se vogliono usare Java, andare avanti!

Se ho già ho costruito una classe in C ++ (e questo è successo il più delle volte) e voglio inviare i dati sul filo ora, Boost serializzazione rende, ovviamente, un sacco di senso (soprattutto dove ho già un Boost la dipendenza da qualche altra parte).

È possibile utilizzare la serializzazione spinta in stretta collaborazione con gli oggetti del dominio "reali", e serializzare la gerarchia degli oggetti completa (eredità). Protobuf non supporta l'ereditarietà, quindi dovrete usare l'aggregazione. Le persone sostengono che Protobuf deve essere utilizzato per DTOs (oggetto di trasferimento dati), e non per se stessi oggetti del dominio principale. Ho usato sia boost :: serializzazione e protobuf. Le prestazioni di boost :: serializzazione deve essere preso in considerazione, cereali potrebbe essere un'alternativa.

So che questa è una domanda più vecchia ormai, ma ho pensato di buttare dentro i miei 2 pence!

Con boost hai l'opportunità di scrivere alcune validazioni dei dati nelle tue lezioni;questo è positivo perché la definizione dei dati e i controlli di validità sono tutti in un unico posto.

Con GPB la cosa migliore che puoi fare è inserire commenti nel file .proto e sperare contro ogni speranza che chi lo sta utilizzando lo legga, gli presti attenzione e implementi lui stesso i controlli di validità.

Inutile dire che questo è improbabile e inaffidabile se ti affidi a qualcun altro all'altra estremità di un flusso di rete per farlo con lo stesso vigore di te stesso.Inoltre, se i vincoli sulla validità cambiano, è necessario pianificare, coordinare ed eseguire più modifiche al codice.

Pertanto ritengo che GPB sia inappropriato per sviluppi in cui ci sono poche opportunità di incontrare e parlare regolarmente con tutti i membri del team.

==MODIFICA==

Il genere di cose che intendo è questo:

message Foo
{
    int32 bearing = 1;
}

Ora chi può dire quale sia l'intervallo valido bearing È?Possiamo avere

message Foo
{
    int32 bearing = 1;  // Valid between 0 and 359
}

Ma questo dipende dal fatto che qualcun altro lo legga e scriva il codice per esso.Ad esempio, se lo modifichi e il vincolo diventa:

message Foo
{
    int32 bearing = 1;  // Valid between -180 and +180
}

dipendi completamente da tutti coloro che hanno utilizzato questo .proto aggiornando il proprio codice.Questo è inaffidabile e costoso.

Almeno con la serializzazione Boost stai distribuendo una singola classe C++ e in essa possono essere integrati controlli di validità dei dati.Se questi vincoli cambiano, nessun altro dovrà fare altro se non assicurarsi di utilizzare la tua stessa versione del codice sorgente.

Alternativa

C'è un'alternativa:ASN.1.Questo è antico, ma ha alcune cose davvero, davvero utili:

Foo ::= SEQUENCE
{
   bearing INTEGER (0..359)
}

Da notare il vincolo.Pertanto, ogni volta che qualcuno utilizza questo file .asn e genera codice, si ritrova con un codice che lo controllerà automaticamente bearing è compreso tra 0 e 359.Se aggiorni il file .asn,

Foo ::= SEQUENCE
{
   bearing INTEGER (-180..180)
}

tutto quello che devono fare è ricompilare.Non sono necessarie altre modifiche al codice.

Puoi anche fare:

bearingMin INTEGER ::= 0
bearingMax INTEGER ::= 360

Foo ::= SEQUENCE
{
   bearing INTEGER (bearingMin..<bearingMax)
}

Notare la <.Inoltre, nella maggior parte degli strumenti cuscinettoMin e cuscinettoMax possono apparire come costanti nel codice generato.È estremamente utile.

I vincoli possono essere piuttosto elaborati:

Garr ::= INTEGER (0..10 | 25..32)

Guarda il capitolo 13 in questo PDF;è incredibile quello che puoi fare;

Anche gli array possono essere vincolati:

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 è vecchio stile, ma ancora attivamente sviluppato, ampiamente utilizzato (il tuo telefono cellulare lo utilizza molto) e molto più flessibile della maggior parte delle altre tecnologie di serializzazione.L'unica carenza che posso notare è che non esiste un generatore di codice decente per Python.Se utilizzi C/C++, C#, Java, ADA, allora sei ben servito da una combinazione di strumenti gratuiti (C/C++, ADA) e commerciali (C/C++, C#, JAVA).

Mi piace particolarmente l'ampia scelta di formati wire binari e basati su testo.Ciò lo rende estremamente conveniente in alcuni progetti.L'elenco dei formati wire attualmente include:

  • BER (binario)
  • PER (binario, allineato e non allineato.Questo è ultra bit efficiente.Ad esempio, e INTEGER vincolato tra 0 E 15 occuperà solo 4 bits sul filo)
  • OER
  • DER (un altro binario)
  • XML (anche XER)
  • JSON (nuovo di zecca, il supporto dello strumento è ancora in fase di sviluppo)

più altri.

Notati gli ultimi due?Sì, puoi definire strutture dati in ASN.1, generare codice ed emettere/consumare messaggi in XML e JSON.Non male per una tecnologia nata negli anni ’80.

Il controllo delle versioni viene eseguito in modo diverso rispetto a GPB.Puoi consentire estensioni:

Foo ::= SEQUENCE
{
   bearing INTEGER (-180..180),
   ...
}

Ciò significa che in un secondo momento potrò aggiungere altro Foo, e i sistemi più vecchi che hanno questa versione possono ancora funzionare (ma possono accedere solo a bearing campo).

Valuto ASN.1 molto bene.Può essere una seccatura da affrontare (gli strumenti potrebbero costare denaro, il codice generato non è necessariamente bello, ecc.).Ma i vincoli sono una caratteristica davvero fantastica che mi ha risparmiato un sacco di dolori al cuore più e più volte.Gli sviluppatori si lamentano molto quando i codificatori/decodificatori segnalano di aver generato dati Duff.

Altri collegamenti:

Osservazioni

Per condividere i dati:

  • Approcci Code First (es.Boost serializzazione) ti limitano alla lingua originale (ad es.C++) o costringerti a fare molto lavoro extra in un'altra lingua
  • Lo schema prima è migliore, ma
    • Molti di questi lasciano grandi lacune nel contratto di condivisione (ad es.nessun vincolo).GPB è fastidioso a questo riguardo, perché per il resto è molto buono.
    • Alcuni hanno dei vincoli (es.XSD, JSON), ma soffrono di un supporto irregolare degli strumenti.
    • Ad esempio, xsd.exe di Microsoft ignora attivamente i vincoli nei file xsd (la scusa di MS è davvero debole).XSD è buono (dal punto di vista dei vincoli), ma se non puoi fidarti che l'altro utilizzi un buon strumento XSD che li imponga per lui/lei, il valore di XSD diminuisce
    • I validatori JSON vanno bene, ma non fanno nulla per aiutarti a formare il JSON in primo luogo e non vengono chiamati automaticamente.Non esiste alcuna garanzia che qualcuno che ti ha inviato un messaggio JSON lo abbia eseguito tramite un validatore.Devi ricordarti di convalidarlo tu stesso.
    • Tutti gli strumenti ASN.1 sembrano implementare il controllo dei vincoli.

Quindi per me ASN.1 lo fa.È quello che ha meno probabilità di far sì che qualcun altro commetta un errore, perché è quello con le giuste funzionalità e dove tutti gli strumenti apparentemente tentano di implementare pienamente tali funzionalità, ed è sufficientemente neutro dal punto di vista linguistico per la maggior parte degli scopi.

Ad essere onesti, se GPB aggiungesse un meccanismo di vincoli sarebbe il vincitore.XSD è vicino ma gli strumenti sono quasi universalmente spazzatura.Se esistessero generatori di codice decenti di altri linguaggi, lo schema JSON sarebbe abbastanza buono.

Se GPB avesse aggiunto dei vincoli (nota:questo non cambierebbe nessuno dei formati wire), sarebbe quello che consiglierei a tutti per quasi tutti gli scopi.Sebbene uPER di ASN.1 sia molto utile per i collegamenti radio.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top