Rapide de sérialisation/désérialisation des structs
J'ai d'énormes amont de données géographiques représentées dans simple la structure de l'objet composé uniquement des structures. Tous mes champs sont de type valeur.
public struct Child
{
readonly float X;
readonly float Y;
readonly int myField;
}
public struct Parent
{
readonly int id;
readonly int field1;
readonly int field2;
readonly Child[] children;
}
Les données sont découpées en place bien à de petites portions de Parent[]
-s. Chaque tableau contient quelques milliers Parent instances. J'ai beaucoup trop de données pour garder tout en mémoire, donc j'ai besoin de swap de ces morceaux sur le disque d'avant en arrière. (Un fichier de résultat env. 2-300 KO).
Quel serait le moyen le plus efficace de la sérialisation/désérialisation du Parent[]
à un byte[]
pour dumpint à disque et de la lecture? Concernant la vitesse, je suis particulièrement intéressé par rapide de la désérialisation, la vitesse d'écriture n'est pas que critique.
Serait simple BinarySerializer
assez bon?
Ou devrais-je pirater autour avec StructLayout
(voir accepté de répondre)? Je ne suis pas sûr si cela fonctionnerait avec le tableau champ de Parent.children
.
Mise à JOUR: Réponse aux commentaires - Oui, les objets sont immuables (code mis à jour) et en effet le children
champ n'est pas le type de valeur. 300KB ne semble pas beaucoup, mais j'ai des milliards de fichiers comme ça, si la vitesse est importante.
children
champ n'est pas un type de valeur.300KB est en petite quantité, ce montant est désérialisé/sérialisé en 0,1 s w/o optimisations
Est toutes vos données en lecture seule?
Le binaire sérialiseur est très lent. Il utilise la réflexion pour injecter des métadonnées dans la sérialisation des données. Car il ne fournit pas de type de métadonnées, XML sérialiseur sérialise les données dans un format plus petit et plus rapide format que le binaire sérialiseur. Dans les deux cas, la sérialisation est faite par l'intermédiaire de la réflexion et est très lent. Un de mes brillants collègues créé un mécanisme de sérialisation binaire qui est 20 fois plus rapide que le sérialiseur XML, qui a été plus rapide que le binaire sérialiseur. Il a été aussi considérablement plus petites.
OriginalL'auteur user256890 | 2012-03-30
Vous devez vous connecter pour publier un commentaire.
BinarySerializer est très générale sérialiseur. Il ne sera pas exécuter ainsi que d'une implémentation personnalisée.
Heureusement pour votre, vos données se compose de structures. Cela signifie que vous serez en mesure de fixer un structlayout à l'Enfant et à juste bit-copier les enfants tableau à l'aide de code non sécurisé à partir d'un byte[] vous avez lu à partir du disque.
Pour les parents, il n'est pas si facile parce que vous avez besoin pour traiter les enfants séparément. Je vous recommande d'utiliser le code unsafe pour copier les bits copiable champs du byte[] vous lire et désérialiser les enfants séparément.
Avez-vous pensé à la cartographie de tous les enfants dans la mémoire en utilisant les fichiers mappés en mémoire? Vous pouvez ré-utiliser les systèmes d'exploitation cache et pas face à la lecture et à l'écriture.
Zéro-copie-la désérialisation d'un Enfant[] ressemble à ceci:
J'ai ajouté un exemple. Si vous voulez zéro-copie vous avez besoin de modifier votre application pour utiliser des pointeurs ou dangereux IO à l'aide de ReadFile (lire directement dans un Enfant[]). Mais ma conjecture est que le seul passage de la copie est vraiment rien. Les processeurs sont bons.
OriginalL'auteur usr
Si vous n'avez pas envie d'aller en bas de la écrire votre propre sérialiseur itinéraire, vous pouvez utiliser le protobuf.net sérialiseur. Voici la sortie d'un petit programme de test:
Il devrait être assez explicite. C'était juste pour une seule course, mais est assez révélateur de la vitesse, j'ai vu (3-5x).
Pour faire de votre structs serializable (avec protobuf.net), il suffit d'ajouter les attributs suivants:
Mise à JOUR:
En fait, l'écriture d'un personnalisé sérialiseur est assez simple, voici un bare-bones de mise en œuvre:
Et voici sa sortie lorsqu'il est exécuté dans un simple test de vitesse:
Évidemment, c'est beaucoup moins souple que les autres approches, mais si la vitesse est vraiment important c'est environ 2-3x plus rapide que le protobuf méthode. Il produit des minimes tailles de fichier, donc l'écriture sur le disque devrait être plus rapide.
OriginalL'auteur markmuetz