Domanda

Voglio capire perché la soluzione di buffer di protocollo per .NET sviluppato da Marc Gravel è veloce quanto lo è.

Posso capire come la soluzione Google originale abbia raggiunto le sue prestazioni:pregenera codice ottimizzato per la serializzazione degli oggetti;Ho scritto alcune serializzazioni a mano e so che è possibile scrivere codice abbastanza veloce in questo modo se si evita la riflessione.Ma la libreria di Marc è una soluzione runtime che utilizza attributi e non produce alcun codice generato.Quindi, come funziona ?

È stato utile?

Soluzione

protobuf-net utilizza un modello strategico;secondo necessità (una sola volta per tipo) utilizza la riflessione per esaminare i tipi e crea un set di serializzatori (basati su un'interfaccia comune) che può utilizzare per serializzare e deserializzare, quindi quando è in uso sta semplicemente attraversando l'insieme noto di serializzatori.

Dentro che cerca di fare un uso sensato della riflessione quando parla con i membri;utilizza Delegate.CreateDelegate parlare con le proprietà e DynamicMethod (e IL personalizzato) per parlare con i campi (quando possibile;dipende dal framework di destinazione).Ciò significa che parla sempre conosciuto tipi di delegati, anziché solo DynamicInvoke (che è molto lento).

Senza impazzire, il codice presenta alcune ottimizzazioni (probabilmente a scapito della leggibilità) in termini di:

  • Locale byte[] buffering (dei flussi di input/output)
  • utilizzando array di dimensione fissa (piuttosto che elenchi, ecc.);forse troppo
  • usare farmaci generici per evitare la boxe
  • numerose modifiche/modifiche/ecc. attorno ai cicli di elaborazione binaria

Col senno di poi, penso di aver commesso un errore sul punto dei generici;la complessità ha comportato l’introduzione forzata dei farmaci generici nel sistema l'ha piegato in alcuni punti, e causa attivamente alcuni grossi problemi (per modelli complessi) su quadro compatto.

Ho alcuni progetti (solo nella mia testa) per rifattorizzarlo utilizzando non-interfacce generiche e invece (per framework idonei) farne un maggiore utilizzo ILGenerator (la mia prima scelta sarebbe stata Expression, ma ciò impone una versione del framework più elevata).Il problema, tuttavia, è che ci vorrà molto tempo prima che funzioni, e fino a tempi molto recenti Sono stato piuttosto sommerso.

Recentemente ci sono riuscito ricominciare a passare un po' di tempo su protobuf-net, quindi spero di eliminare il mio arretrato di richieste ecc. e di iniziare presto.È anche mia intenzione farlo funzionare con i modelli altro rispetto alla riflessione (ad es.descrivendo separatamente la mappatura dei cavi).


e non produce alcun codice generato

Dovrei anche chiarire che ci sono due percorsi di codegen (facoltativi) se si desidera utilizzare il codice generato;protogen.exe o il Componente aggiuntivo VS, consentono la generazione di codice da un file .proto.Ma non è così necessario - è utile principalmente se si dispone di un file .proto esistente o si intende interagire con un altro linguaggio (C++ ecc.) per lo sviluppo basato sul contratto.

Altri suggerimenti

La sua performance molto buona!

Si può vedere un confronto completo tra diversi formati tra cui protobuf fatto da me- http : //maxondev.com/serialization-performance-comparison-c-net-formats-frameworks-xmldatacontractserializer-xmlserializer-binaryformatter-json-newtonsoft-servicestack-text/

Questo confronto comprende campioni grandi e piccoli di dati e formati diversi.

Una delle prove della mia post- entrare descrizione dell'immagine qui

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