Rapide et compact sérialisation d'un objet dans .NET
Je veux utiliser la sérialisation d'un objet de communiquer sur le réseau entre un Mono serveur et les clients de Silverlight.
Il est très important que la sérialisation est efficace de l'espace et assez vite, que le serveur va accueillir plusieurs temps réel jeux.
Quelle technique dois-je utiliser? Le BinaryFormatter ajoute beaucoup de frais généraux à sérialisé de cours (Version, la culture, le nom de la classe, les noms de propriété, etc.) ce n'est pas nécessaire à l'intérieur de cette application.
Que puis-je faire pour que ce soit plus efficace de l'espace?
- Oh pinaise! Arrivé une heure trop tard ;-p
Vous devez vous connecter pour publier un commentaire.
Vous pouvez utiliser Protocol Buffers. Je vais changer tout mon code de sérialisation de BinaryFormatter avec la compression de Protocole de Tampons et d'obtenir de très bons résultats. Il est plus efficace dans l'espace et le temps.
Il y a deux .NET implémentations par Jon Skeet et Marc Gravel.
Mise À Jour: Officiel .NET de la mise en œuvre peut être trouvé ici.
J'ai quelques repères pour le leader .NET sérialiseurs basés sur les Comptoirs de dataset.
@marcgravell binaire protobuf-net est le plus rapide implémentations étalonnés qui est sur le 7x plus rapide que Microsoft plus rapide sérialiseur disponible (le XML DataContractSerializer) dans la BCL.
J'ai aussi de maintenir une certaine open-source de haute performance .NET texte sérialiseurs ainsi:
Json serializer
est beaucoup plus petite que laBinaryFormatter
, comment ont-ils tester cela? J'ai écrit mes propres sérialiseur qui est très similaire à laBinaryFormatter
et les résultats sont très différents. La plage est de 1:1 à 1:7.87 de la taille du fichier pour mon formateur. "Ne jamais faire confiance à des statistiques que vous ne l'avez pas vous-même falsifiées"BinaryFormatter
la taille du fichier est beaucoup plus faible lors de l'utilisation d'objets complexes. La sérialisation d'un tas de petits objets pour le formateur n'a pas de sens( il soutient beaucoup d'informations lors de l'appel deSerialize
pour chacun de ces objets ), lors de l'utilisation d'un tableau au lieu de la taille du fichier est beaucoup plus petite.Comme l'auteur, je vous invite à essayer protobuf-net; il est livré avec les fichiers binaires pour les deux Mono 2.0 et Silverlight 2.0, et est rapide et efficace. Si vous avez quelque problème que ce soit, envoyez-moi un e-mail (voir mon Stack Dépassement de profil), le support est gratuit.
De Jon version (voir ci-dessus, a accepté de répondre) est également très bon, mais l'OMI le protobuf-net version est plus idiomatique pour C# - Jon serait idéal si vous parliez, C#, Java, donc vous pourriez avoir une API similaire à ses deux extrémités.
ProtoContract
- il fonctionnera également avec[XmlType]+[XmlElement(Order=n)]
ou[DataContract]+[DataMember(Order=n)]
.J'ai eu un problème similaire, même si je suis juste à l'aide .NET. J'ai voulu envoyer des données sur Internet aussi rapidement et facilement que possible. Je n'ai pas trouver quelque chose qui serait assez optimisé, j'ai donc fait mon propre sérialiseur, nommé NetSerializer.
NetSerializer a ses limites, mais ils n'affectent pas mon cas d'utilisation. Et je n'ai pas fait de points de référence pour un certain temps, mais il était beaucoup beaucoup plus rapide que n'importe quoi d'autre, j'ai trouvé.
Je n'ai pas essayé sur Mono ou Silverlight. Je serais prêt à parier qu'il fonctionne sur Mono, mais je ne suis pas sûr de ce que le niveau de soutien est pour DynamicMethods sur Silverlight.
Vous pouvez essayer d'utiliser JSON. Ce n'est pas aussi efficaces que les Tampons de Protocole, mais il serait beaucoup plus facile de surveiller les messages avec des outils comme Wireshark, ce qui aide beaucoup quand le débogage des problèmes. .NET 3.5 est livré avec un sérialiseur JSON.
Vous pouvez transmettre les données par le biais d'un DeflateStream ou GZipStream de le compresser avant la transmission. Ces classes vivre dans la Système.IO.La Compression espace de noms.
J'ai eu un problème similaire - sauvegarder un fichier. Mais la suite peut également être utilisé sur un réseau tel qu'il a été conçu pour l'accès distant.
La solution est d'utiliser Simon Hewitt bibliothèque - voir L'optimisation de
La sérialisation dans .NET - partie 2.
Partie 1 de l'article, les états (le gras est de mon accent):
"... Si vous avez déjà utilisé .NET remoting pour de grandes quantités de
les données, vous aurez constaté qu'il y a des problèmes avec
l'évolutivité. Pour de petites quantités de données, il fonctionne bien
assez, mais de plus grandes quantités de prendre beaucoup de CPU et de la mémoire,
générer des quantités massives de données pour la transmission, et
peut échouer avec De la Mémoire des exceptions. Il ya aussi une grande
problème avec le temps nécessaire pour effectuer l'
la sérialisation - de grandes quantités de données peut rendre impossible l'
pour une utilisation dans les applications ...."
J'ai obtenu un résultat similaire pour mon application particulière, 40
les temps de sauvegarde plus rapide et 20 fois plus rapide chargement (à partir de
minutes secondes). La taille des données a été sérialisé
aussi beaucoup plus réduite. Je ne me souviens pas exactement, mais il
a au moins 2-3 fois.
Il est assez facile d'obtenir commencé. Néanmoins, il est un
gotcha: utilisez uniquement .NET de la sérialisation pour le très haut
niveau de discbased (pour faire de la sérialisation/deserialisation
commencé) et ensuite appeler la sérialisation/deserialisation
fonctions directement dans les champs plus haut niveau
discbased. Sinon il n'y aura pas de speed-up...
Par exemple, si une structure de données (dire
Generic.List
) n'est pas pris en charge par la bibliothèque .NETla sérialisation sera utilisé à la place et c'est un non-non. Au lieu de cela
serialise la liste dans le code client (ou similaire). Pour un exemple
voir de près "" C'est notre propre codage." dans la même fonction
comme indiqué ci-dessous.
Pour référence: le code de mon application - voir de près "Remarque: c'est le seul endroit où nous utilisons de l'intégré .NET ...".
Vous pouvez essayer de BOIS qui se concentre sur les paniers de la taille des données et offre le meilleur de l'emballage jusqu'à présent. (Je n'ai pas vu une meilleure optimisation encore).
https://github.com/salarcode/Bois
reconsider you data storage strategy
<-- savez-vous que certaines entreprises ont toujours besoin développeurs mainframe? Mon point est que, parfois, vous ne pouvez pas changer la façon dont l'héritage code est écrit sous le capot. C'est comme la vieille voiture vs new. Oui, l'achat d'une Maserati va résoudre votre problème, mais avez-vous des plus de 200K $, si tout ce qui est nécessaire est un moteur de reconstruction pour 3K $?