Question

Je veux comprendre pourquoi la solution de tampons de protocole pour .NET développé par Marc Gravell est aussi vite qu'il est.

Je peux comprendre comment la solution Google originale atteint ses performances: il génère une pré-code optimisé pour la sérialisation d'objets; J'ai écrit une sérialisation à la main et je sais qu'il est possible d'écrire du code assez rapide de cette façon si vous évitez la réflexion. Mais la bibliothèque de Marc est une solution d'exécution qui utilise des attributs et ne produit pas de code généré. Alors, comment ça marche ?

Était-ce utile?

La solution

protobuf-net utilise un modèle de stratégie; au besoin (une seule fois par type), il utilise la réflexion pour examiner les types, et construit un ensemble de serializers (basé sur une interface commune) qu'il peut utiliser pour sérialiser et désérialiser - donc lors de l'utilisation il redouble seulement par l'ensemble connu de serializers.

l'intérieur qui, il essaie de faire usage raisonnable de réflexion quand on parle aux membres; il utilise Delegate.CreateDelegate pour parler aux propriétés et DynamicMethod (et la coutume IL) pour parler aux champs (lorsque cela est possible, cela dépend du cadre cible). Cela signifie qu'il parle toujours connu types de délégués, plutôt que DynamicInvoke (ce qui est très lent).

Sans fou, le code a quelques Optimisations (sans doute au détriment de la lisibilité) en termes de:

  • tampon de byte[] local (d'entrée / flux de sortie)
  • en utilisant des réseaux de taille fixe (plutôt que des listes, etc.); peut-être trop
  • en utilisant génériques pour éviter la boxe
  • de nombreux tweaks / twiddles / etc autour des boucles de traitement binaire

Avec le recul, je pense que je fait une erreur sur le point de médicaments génériques; la complexité signifiait que forcer les médicaments génériques dans le système plié hors de forme dans quelques endroits , et provoque activement des problèmes majeurs (pour les modèles complexes) sur cadre compact.

J'ai quelques dessins (dans ma tête seulement) Refactor cela en utilisant non interfaces -Générique, et à la place (pour les cadres appropriés) utiliser davantage ILGenerator (mon premier choix aurait été Expression , mais qui force une version cadre supérieur). Le problème, cependant, est que cela va prendre beaucoup de temps pour travailler, et jusqu'à très récemment J'ai assez débordée .

Récemment, j'ai réussi à commencer à passer du temps sur protobuf -net à nouveau , alors je espère que je vais effacer mon arriéré de demandes, etc et commencer ce bientôt. Il est aussi mon intention de le faire fonctionner avec des modèles autre que la réflexion (à savoir décrivant la correspondance de fil séparément).


  

et ne produit pas de code généré

Je tiens également à préciser qu'il existe deux (en option) des itinéraires Codegen si vous souhaitez utiliser le code généré; add-in protogen.exe, ou VS , permettre la génération de code à partir d'un fichier .proto. Mais ce n'est pas besoin -. Il est utile surtout si vous avez un fichier .proto existant ou intention de interopérer avec une autre langue (C ++, etc.) pour le développement du contrat premier

Autres conseils

Ses performances très bon!

Vous pouvez voir une comparaison complète entre les différents formats, y compris protobuf effectuées par moi- http : //maxondev.com/serialization-performance-comparison-c-net-formats-frameworks-xmldatacontractserializer-xmlserializer-binaryformatter-json-newtonsoft-servicestack-text/

Cette comparaison comprend de grandes et de petits échantillons de données et différents formats.

L'un des tests dans mon post entrer image description ici

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top