11
votes

Serialising et désérialisant V.Large Dictionnaire en C #

Nous avons un V.Large Dictionnaire (plusieurs millions d'entrées) dans le cadre d'une application C # haute performance. Lorsque l'application se ferme, nous sérialisons le dictionnaire sur le disque à l'aide de Binarinformatter et MemoryStream.toarray () . La sérialisation revient dans environ 30 secondes et produit un fichier d'environ 200 Mo de taille. Lorsque nous essayons ensuite de désérialiser le dictionnaire en utilisant le code suivant: xxx

Il faut environ 15 minutes pour revenir. Nous avons essayé des alternatives et la partie lente est définitivement bin.derséralize (flux) , c'est-à-dire que les octets sont lus à partir du disque dur (SSD haute performance) en moins de 1 seconde.

Quelqu'un peut-il souligner ce que nous faisons mal car nous voulons que l'heure de chargement du même ordre que le temps de conservation.

Cordialement, Marc


6 commentaires

Quel est le type de dictionnaire? C'EST À DIRE. Est-ce comme: Dictionnaire ?


Je viens de réaliser que j'avais ajouté cela à la poste originale, mais c'était à l'intérieur des supports triangulaires, alors ne vous apparaissiez pas. Le dictionnaire est (long, uint).


Hmm. Intéressant. J'aurais pu être assermenté il y aurait eu des cordes impliquées - beaucoup d'allocations de chaînes sur le tas.


Super idée folle ici, mais y pas sql?


C'est la limite de performance de notre application - Insérer le temps et la lecture de MSSQL est d'environ 5 ms, à partir du dictionnaire, il est inférieur à la moitié qui nous donne un bon facteur de deux améliorations.


+1 pour Will. Peut-être que SQLite pourrait être un bon ajustement


4 Réponses :


2
votes

Vous voudrez peut-être utiliser un profileur pour voir si, dans les coulisses, le désérialiseur effectue une bouquet de réflexion à la mouche.

Pour le moment, si vous ne voulez pas utiliser une base de données, essayez de stocker vos objets comme un flûti à un format personnalisé. Par exemple, la première ligne Le fichier donne le nombre total d'entrées dans le dictionnaire, vous permettant d'instancier un dictionnaire avec une taille prédéterminée. Avoir les lignes restantes en tant que série de paires de la valeur de clé à largeur fixe représentant toutes les entrées de votre dictionnaire.

Avec votre nouveau format de fichier, utilisez un StreamReder à lire dans votre fichier ligne-ligne ou dans des blocs fixes, voir si cela vous permet de lire dans votre dictionnaire tout plus rapidement.


1 commentaires

Bon point sur le dimensionnement du dictionnaire avant d'ajouter les entrées. Lors de l'enquête sur cette approche, je suggérerais d'utiliser un écrivain BinaryReader \ en lisant des millions de cordes, créant des millions de cordes, puis d'analyser des millions de longs et des ulongs hors de ces chaînes auront des problèmes de performance.



11
votes

Vous pouvez vérifier protobuf-net ou simplement le sérialiser vous-même. Ce qui sera probablement le plus rapide que vous puissiez obtenir. XXX

Taille du fichier résultant => 90 millions d'octets (85,8 Mo).


2 commentaires

Il suffit de courir ce code à l'aide d'un dictionnaire avec des paires de 20 m de la valeur de clé, produisant un fichier 234MB de taille. Performance sur un I7 (4GHz) - 8 Go DDR3 RAM - Vertex 2 SSD Disque dur: Dictionnaire Construire et écrire au fichier Time - 2.17Secs Dictionnaire lire depuis le fichier et le temps de reconstruction - 15.39Secs Si nous pouvons conserver ce type de performance, il devrait fonctionner très bien.


Je viens de terminer la mise en œuvre de cette solution dans notre application réelle et les résultats étaient similaires aux temps de performance postés par moi précédemment (c'est-à-dire excellent). J'étais un peu inquiet d'avoir des clés non consécutives pourraient causer un problème, mais c'était injustifié (ne semble pas faire une différence). Encore beaucoup merci !!



1
votes

Il existe plusieurs solutions NOSQL à valeur rapide, pourquoi ne pas les essayer? À titre d'exemple esent, quelqu'un l'a posté ici. ManageDesent


0 commentaires

6
votes

Juste pour montrer une sérialisation similaire (à la réponse acceptée) via Protobuf-Net: XXX

Taille: 83meg - mais surtout, vous n'avez pas eu à faire tout à la main, introduire des bugs. Rapide aussi (sera encore plus rapide dans "V2").


0 commentaires